diff -r -u sqwebmail-3.6.0-orig/cgi/cgi.c sqwebmail-3.6.0/cgi/cgi.c --- sqwebmail-3.6.0-orig/cgi/cgi.c 2003-07-08 00:19:13.000000000 +0900 +++ sqwebmail-3.6.0/cgi/cgi.c 2003-12-30 12:04:34.000000000 +0900 @@ -86,6 +86,8 @@ void cgi_setup() { + //ichikawa + //sleep(20); struct cgi_arglist *p; cgi_setup_1(); @@ -360,8 +362,14 @@ q=nybble(q, &c); q=nybble(q, &c); +//ichikawa +// this corrupts 8-bit coding character +// e.x. japanese word "shoubu" in utf-8 is "%E5%8B%9D%E8%B2%A0" +// last "%A0" is a part of character, is not space. +#if 0 if ((char)c == (char)0xA0) c=' '; /* See above */ +#endif if (c && c != '\r') /* Ignore CRs we get in TEXTAREAS */ diff -r -u sqwebmail-3.6.0-orig/rfc2045/rfc2045.c sqwebmail-3.6.0/rfc2045/rfc2045.c --- sqwebmail-3.6.0-orig/rfc2045/rfc2045.c 2003-04-10 09:33:09.000000000 +0900 +++ sqwebmail-3.6.0/rfc2045/rfc2045.c 2004-01-13 01:57:45.000000000 +0900 @@ -1198,6 +1198,14 @@ *charset_s=c; } +//ichikawa +#if 1 //mime +const char *rfc2045_content_charset="utf-8"; +const char *rfc2045_getdefaultcharset() +{ + return rfc2045_content_charset; +} +#else const char *rfc2045_getdefaultcharset() { const char *p=rfc2045_defcharset; @@ -1205,6 +1213,7 @@ if (!p) p=RFC2045CHARSET; return (p); } +#endif void rfc2045_setdefaultcharset(const char *charset) { diff -r -u sqwebmail-3.6.0-orig/rfc2045/rfc2045reply.c sqwebmail-3.6.0/rfc2045/rfc2045reply.c --- sqwebmail-3.6.0-orig/rfc2045/rfc2045reply.c 2003-06-21 05:49:48.000000000 +0900 +++ sqwebmail-3.6.0/rfc2045/rfc2045reply.c 2004-01-13 01:06:17.000000000 +0900 @@ -829,8 +829,15 @@ if (s) free(s); free(subject); } - +//ichikawa +#if 1 + writes(ri, "\n"); + writes(ri, "Content-Type: text/plain; charset=\""); + writes(ri, ri->charset); + writes(ri, "\"\n\n"); +#else writes(ri, "\n\n"); +#endif if (whowrote) { writes(ri, whowrote); diff -r -u sqwebmail-3.6.0-orig/rfc2045/rfc2646create.c sqwebmail-3.6.0/rfc2045/rfc2646create.c --- sqwebmail-3.6.0-orig/rfc2045/rfc2646create.c 2003-03-17 02:25:11.000000000 +0900 +++ sqwebmail-3.6.0/rfc2045/rfc2646create.c 2004-01-04 22:30:32.000000000 +0900 @@ -22,7 +22,12 @@ p->handler=f; p->voidarg=vp; +//ichikawa +#if 1 // mine + p->linesize=997; +#else p->linesize=76; +#endif p->sent_firsttime=1; return (p); } diff -r -u sqwebmail-3.6.0-orig/rfc2045/rfc2646reply.c sqwebmail-3.6.0/rfc2045/rfc2646reply.c --- sqwebmail-3.6.0-orig/rfc2045/rfc2646reply.c 2003-03-17 02:25:11.000000000 +0900 +++ sqwebmail-3.6.0/rfc2045/rfc2646reply.c 2004-01-12 00:29:09.000000000 +0900 @@ -7,6 +7,9 @@ #include "rfc2646.h" #include #include +//ichikawa +// get_next_a_character_length() +#include "../rfc822/rfc2047.h" static const char rcsid[]="$Id: rfc2646reply.c,v 1.4 2003/03/07 00:47:31 mrsam Exp $"; @@ -120,8 +123,18 @@ return (rc); continue; } +//ichikawa +#if 1 //mime + for(l=0;l<=txtlen;l+=i) { + // FIXME: we assume txt is utf-8 + i=get_next_a_character_length(txt+l, "utf-8"); + if (l+i > maxlen) + break; + } +#else if (l > maxlen) l=maxlen; +#endif memcpy(p->replybuffer, txt, l); p->replylen=l; txt += l; diff -r -u sqwebmail-3.6.0-orig/rfc822/rfc2047.c sqwebmail-3.6.0/rfc822/rfc2047.c --- sqwebmail-3.6.0-orig/rfc822/rfc2047.c 2003-03-23 13:50:43.000000000 +0900 +++ sqwebmail-3.6.0/rfc822/rfc2047.c 2003-12-28 23:46:45.000000000 +0900 @@ -8,6 +8,8 @@ #include #include #include +//ichikawa +#include #include "rfc822.h" #include "rfc2047.h" @@ -16,6 +18,15 @@ static const char xdigit[]="0123456789ABCDEF"; +// ichikawa +extern const char *sqwebmail_content_charset; +extern const char *sqwebmail_outgoing_charset; +//#if HAVE_UNICODE +#if HAVE_LIBUNICODE +#include "../unicode/unicode.h" +#endif + + static char *rfc2047_search_quote(const char **ptr) { const char *p= *ptr; @@ -275,18 +286,82 @@ return (rc); } +//ichikawa +static int do_enhanced_new(const char *txt, int len, const char *chset, + const char *lang, + void *arg, + int (*func)(const char *, int, const char *, + const char *, void *) + ) +{ +int rc=0; +struct simple_info *info=(struct simple_info *)arg; +#if HAVE_LIBUNICODE +int convert_flag=0; +char *p, *q; +#endif + if (chset && info->mychset && strcasecmp(chset, info->mychset) == 0) + chset=0; + +#if HAVE_LIBUNICODE + if (chset && info->mychset) + { + const struct unicode_info *src_chset= + unicode_find(chset); + const struct unicode_info *dst_chset= + unicode_find(info->mychset); + p=malloc(sizeof(char)*(len+3)); + strncpy(p,txt,len); + p[len]=0; + q=unicode_xconvert(p, src_chset, dst_chset); + convert_flag=1; + chset=0; + free(p); + } +#endif + + if (chset) + { + rc= (*func)(" [", 2, 0, 0, arg); + if (rc == 0) + rc= (*func)(chset, strlen(chset), 0, 0, arg); + if (rc == 0 && lang) + rc= (*func)("*", 1, 0, 0, arg); + if (rc == 0 && lang) + rc= (*func)(lang, strlen(lang), 0, 0, arg); + if (rc == 0) + rc= (*func)("] ", 2, 0, 0, arg); + } + +#if HAVE_LIBUNICODE + if (convert_flag == 1) + { + rc= (*func)(q, strlen(q), 0, 0, arg); + free(q); + return (rc); + } +#endif + if (rc == 0) + rc= (*func)(txt, len, 0, 0, arg); + return (rc); +} + static int count_enhanced(const char *txt, int len, const char *chset, const char *lang, void *arg) { - return (do_enhanced(txt, len, chset, lang, arg, &count_simple)); + //ichikawa + // return (do_enhanced(txt, len, chset, lang, arg, &count_simple)); + return (do_enhanced_new(txt, len, chset, lang, arg, &count_simple)); } static int save_enhanced(const char *txt, int len, const char *chset, const char *lang, void *arg) { - return (do_enhanced(txt, len, chset, lang, arg, &save_simple)); + //ichikawa + // return (do_enhanced(txt, len, chset, lang, arg, &save_simple)); + return (do_enhanced_new(txt, len, chset, lang, arg, &save_simple)); } char *rfc2047_decode_enhanced(const char *text, const char *mychset) @@ -309,24 +384,58 @@ return (info.string); } +//ichikawa +char *rfc2047_decode_enhanced_new(const char *text, const char *mychset, + const char *outchset) +{ +struct simple_info info; + + info.mychset=mychset; + info.index=1; + if (rfc2047_decode(text, &count_enhanced, &info)) + return (0); + + if ((info.string=malloc(info.index)) == 0) return (0); + info.index=0; + if (rfc2047_decode(text, &save_enhanced, &info)) + { + free(info.string); + return (0); + } + info.string[info.index]=0; + return (info.string); +} + void rfc2047_print(const struct rfc822a *a, const char *charset, void (*print_func)(char, void *), void (*print_separator)(const char *, void *), void *ptr) { - rfc822_print_common(a, &rfc2047_decode_enhanced, charset, +//ichikawa + rfc822_print_common(a, &rfc2047_decode_enhanced_new, charset, charset, print_func, print_separator, ptr); } static char *a_rfc2047_encode_str(const char *str, const char *charset); +//ichikawa +static char *a_rfc2047_encode_str_new(const char *str, const char *charset, + const char *outgoing_charset); + +//ichikawa static void rfc2047_encode_header_do(const struct rfc822a *a, - const char *charset, + const char *charset, const char *outgoing_charset, void (*print_func)(char, void *), void (*print_separator)(const char *, void *), void *ptr) { +//ichikawa +#if 1 + rfc822_print_common(a, &a_rfc2047_encode_str_new, charset, + outgoing_charset, print_func, print_separator, ptr); +#else rfc822_print_common(a, &a_rfc2047_encode_str, charset, print_func, print_separator, ptr); +#endif } /* @@ -343,12 +452,20 @@ if (l == 0) return (strdup(str)); + // ichikawa +#if 1 if (*str == '"' && str[l-1] == '"') ; else if (*str == '(' && str[l-1] == ')') ; else return (rfc2047_encode_str(str, charset)); +#else + if (*str == '(' && str[l-1] == ')') + ; + else + return (rfc2047_encode_str(str, charset)); +#endif foo= *str; bar[0]= str[l-1]; @@ -389,10 +506,30 @@ char *s, *p; l=1; - rfc2047_encode_header_do(a, charset, &count, &counts2, &l); + //ichikawa + rfc2047_encode_header_do(a, charset, charset, &count, &counts2, &l); if ((s=malloc(l)) == 0) return (0); p=s; - rfc2047_encode_header_do(a, charset, &save, &saves2, &p); + //ichikawa + rfc2047_encode_header_do(a, charset, charset, &save, &saves2, &p); + *p=0; + return (s); +} + +//ichikawa +char *rfc2047_encode_header_new(const struct rfc822a *a, + const char *charset, const char *outgoing_charset) +{ +size_t l; +char *s, *p; + + l=1; + rfc2047_encode_header_do(a, charset, outgoing_charset, + &count, &counts2, &l); + if ((s=malloc(l)) == 0) return (0); + p=s; + rfc2047_encode_header_do(a, charset, outgoing_charset, + &save, &saves2, &p); *p=0; return (s); } @@ -582,3 +719,699 @@ *p=0; return (s); } + + + +//ichikawa +static char *a_rfc2047_encode_str_new(const char *str, const char *charset, + const char *outgoing_charset) +{ +size_t i=1; +char *s, *p; + + (void)rfc2047_addr_encode_callback(str, charset, outgoing_charset, + &count_char, &i); + if ((s=malloc(i)) == 0) return (0); + p=s; + (void)rfc2047_addr_encode_callback(str, charset, outgoing_charset, + &save_char, &p); + *p=0; + return (s); +} + +//ichikawa +extern int is_phrase_q_encode (const unsigned char a); +extern int is_comment_q_encode (const unsigned char a); + +//ichikawa +int rfc2047_addr_encode_callback(const char *str, const char *charset, + const char *outgoing_charset, + int (*func)(const char *, size_t, void *), void *arg) +{ +size_t i,pos,rc; +int quote_flag, comment_depth, encode_flag, s; + + /* assume that field name length offset is 10 character */ + pos = 10; + + i = 0; /* parsing pointer */ + /* state holder */ + quote_flag = 0; + comment_depth = 0; + encode_flag = 0; + s = 0; /* the tail of word for consecutive encoding */ + /* state value (N: positive integer, *: any value) + * q=0 c=0 e=* s=*: inside phrase or addr-part + * q=1 c=0 e=* s=*: inside quoted-string + * q=0 c=N e=* s=*: inside comment + * q=* c=* e=0 s=0: no need to encode from head to parsing pointer + * q=* c=* e=1 s=0: need to encode from head to parsing pointer + * q=* c=* e=0 s=N: need to encode from head to N-th character + * and under searching of consecutive encoding + */ + + while(str[i]) + { + /* whether it should be encoded */ + if (str[i] & 0x80) + { + encode_flag=1; + s=0; + i++; + } + else if (str[i]=='"' && comment_depth==0) + { + if (quote_flag == 0) + quote_flag = 1; + else + if (i > 0 && str[i-1] != '\\') + quote_flag = 0; + i++; + } + else if (str[i]=='(' && quote_flag==0) + { + comment_depth++; + if (encode_flag == 1) + { + if (comment_depth == 1) + rc=rfc2047_encode_callback_new(str, i, charset, + outgoing_charset, &pos, + is_phrase_q_encode, func, arg); + else + rc=rfc2047_encode_callback_new(str, i, charset, + outgoing_charset, &pos, + is_comment_q_encode, func, arg); + } + else if (s > 0) + { + if (comment_depth == 1) + rc=rfc2047_encode_callback_new(str, s, charset, + outgoing_charset, &pos, + is_phrase_q_encode, func, arg); + else + rc=rfc2047_encode_callback_new(str, s, charset, + outgoing_charset, &pos, + is_comment_q_encode, func, arg); + if (rc) return (rc); + str+=s; + i-=s; + s=0; + rc=(*func)(str, i, arg); + pos+=i; + } + else + { + rc=(*func)(str, i, arg); + pos+=i; + } + if (rc) return (rc); + str+=i; + i=0; + /* output '(' */ + rc=(*func)(str, 1, arg); + if (rc) return (rc); + str+=1; + pos+=1; + } + else if (str[i]==')' && quote_flag==0) + { + comment_depth--; + if (encode_flag == 1) + rc=rfc2047_encode_callback_new(str, i, charset, + outgoing_charset, &pos, + is_comment_q_encode, func, arg); + else if (s > 0) + { + rc=rfc2047_encode_callback_new(str, s, charset, + outgoing_charset, &pos, + is_comment_q_encode, func, arg); + if (rc) return (rc); + str+=s; + i-=s; + s=0; + rc=(*func)(str, i, arg); + pos+=i; + } + else + { + rc=(*func)(str, i, arg); + pos+=i; + } + if (rc) return (rc); + str+=i; + i=0; + /* output ')' */ + rc=(*func)(str, 1, arg); + if (rc) return (rc); + str+=1; + pos+=1; + } + else if (str[i]==',' && (quote_flag==0||comment_depth==0)) + { + if (encode_flag == 1) + rc=rfc2047_encode_callback_new(str, i, charset, + outgoing_charset, &pos, + is_phrase_q_encode, func, arg); + else if (s > 0) + { + rc=rfc2047_encode_callback_new(str, s, charset, + outgoing_charset, &pos, + is_phrase_q_encode, func, arg); + if (rc) return (rc); + str+=s; + i-=s; + s=0; + rc=(*func)(str, i, arg); + pos+=i; + } + else + { + rc=(*func)(str, i, arg); + pos+=i; + } + if (rc) return (rc); + str+=i; + i=0; + /* output ',' */ + rc=(*func)(str, 1, arg); + if (rc) return (rc); + str+=1; + pos+=1; + } + else if ((str[i]==' '||str[i]=='\t') && quote_flag==0) + { + if (encode_flag == 1) + { + encode_flag=0; + s=i; + while (str[i]==' '||str[i]=='\t') + i++; + continue; + } + else if (s > 0) + { + if (comment_depth == 0) + rc=rfc2047_encode_callback_new(str, s, charset, + outgoing_charset, &pos, + is_phrase_q_encode, func, arg); + else + rc=rfc2047_encode_callback_new(str, s, charset, + outgoing_charset, &pos, + is_comment_q_encode, func, arg); + if (rc) return (rc); + str+=s; + i-=s; + s=0; + rc=(*func)(str, i, arg); + pos+=i; + } + else + { + rc=(*func)(str, i, arg); + pos+=i; + } + if (rc) return (rc); + str+=i; + i=0; + /* output ' ' or '\t' */ + rc=(*func)(str, 1, arg); + if (rc) return (rc); + str+=1; + pos+=1; + } + else + { + i++; + } + } + /* output rest stuff */ + if (encode_flag == 1) + rc=rfc2047_encode_callback_new(str, i, charset, + outgoing_charset, &pos, + is_phrase_q_encode, func, arg); + else if (s > 0) + { + rc=rfc2047_encode_callback_new(str, s, charset, + outgoing_charset, &pos, + is_phrase_q_encode, func, arg); + if (rc) return (rc); + str+=s; + i-=s; + s=0; + rc=(*func)(str, i, arg); + pos+=i; + } + else + { + rc=(*func)(str, i, arg); + pos+=i; + } + if (rc) return (rc); + str+=i; + i=0; + + return (0); +} + +//ichikawa +char *rfc2047_encode_str_new(const char *str, const char *charset, + const char *outgoing_charset) +{ +size_t i=1; +char *s, *p; + + (void)rfc2047_text_encode_callback(str, charset, outgoing_charset, + &count_char, &i); + if ((s=malloc(i)) == 0) return (0); + p=s; + (void)rfc2047_text_encode_callback(str, charset, outgoing_charset, + &save_char, &p); + *p=0; + return (s); +} + +//ichikawa +int is_rfc2047_text_encode (const unsigned char a) +{ + if (a & 0x80) + return (1); + return (0); +} + +//ichikawa +int is_rfc2047_text_delimiter (const unsigned char a) +{ + if (a == ' ' || a == '\t') + return (1); + return (0); +} + +//ichikawa +extern int is_text_q_encode (const unsigned char a); + +//ichikawa +int rfc2047_text_encode_callback(const char *str, const char *charset, + const char *outgoing_charset, + int (*func)(const char *, size_t, void *), void *arg) +{ +size_t i,c,pos,rc; + + /* assume that field name length offset is 10 character */ + pos = 10; + + while (*str) + { + /* Scan of str */ + /* Find the first character to start encoding */ + for (i=0; str[i]; i++) + if (is_rfc2047_text_encode(str[i])) + break; + /* No more character to encode */ + if (str[i] == 0) + return ( i ? (*func)(str, i, arg):0); + /* Find the head of the word to encode */ + while (i) + { + --i; + if (is_rfc2047_text_delimiter(str[i])) + { + ++i; + break; + } + } + /* Output previous words which doesn't need to encode */ + /* and Shift *str to the head of the word to encode */ + if (i) + { + rc=(*func)(str, i, arg); + if (rc) return (rc); + str += i; + pos += i; + i=0; + } + /* Find where to stop MIME encoding */ + /* Consecutive MIME-encoded words are MIME-encoded together */ + for (;;) + { + /* Proceed to the tail of current word */ + for ( ; str[i]; i++) + if (is_rfc2047_text_delimiter(str[i])) + break; + /* No more string, it's where to stop encode */ + if (str[i] == 0) + break; + /* Skip consecutive delimiter to check next word */ + for (c=i; str[c] && is_rfc2047_text_delimiter(str[c]); c++) + ; + /* Scan the next word until we find delimiter or encode char */ + for (; str[c]; c++) + if (is_rfc2047_text_delimiter(str[c]) || + is_rfc2047_text_encode(str[c])) + break; + /* If it's delimiter, next word doesn't need encode */ + /* it's where to stop encode */ + if (str[c] == 0 || is_rfc2047_text_delimiter(str[c])) + break; + /* If not it's delimiter, next word need encode */ + /* We have to encode these words together */ + /* Proceed to check to more next word: Keep looping */ + i=c; + } + /* then, we find where to stop encode */ + /* Output MIME-encoding word */ + rfc2047_encode_callback_new(str, i, charset, + outgoing_charset, &pos, + is_text_q_encode, func, arg); + str += i; + } + return (0); +} + +//ichikawa +/* FIXME: this function SHOULD be migrated into unicode_info */ +int get_next_a_character_length (const char *txt, const char *chset) +{ +char *p, *q; + + if (!chset) + return (1); + p=strdup(chset); + if (!p) + return (1); + for (q=p; *q; q++) + *q=toupper(*q); + + if (strcmp("UTF-8", p) == 0) + { + free(p); + if ((txt[0] & 0x80) == 0) + return (1); + if ((txt[0] & 0xE0) == 0xC0) + if ((txt[1] & 0xC0) == 0x80) + return (2); + if ((txt[0] & 0xF0) == 0xE0) + if ((txt[1] & 0xC0) == 0x80) + if ((txt[2] & 0xC0) == 0x80) + return (3); + if ((txt[0] & 0xF8) == 0xF0) + if ((txt[1] & 0xC0) == 0x80) + if ((txt[2] & 0xC0) == 0x80) + if ((txt[3] & 0xC0) == 0x80) + return (4); + if ((txt[0] & 0xFC) == 0xF8) + if ((txt[1] & 0xC0) == 0x80) + if ((txt[2] & 0xC0) == 0x80) + if ((txt[3] & 0xC0) == 0x80) + if ((txt[4] & 0xC0) == 0x80) + return (5); + if ((txt[0] & 0xFE) == 0xFC) + if ((txt[1] & 0xC0) == 0x80) + if ((txt[2] & 0xC0) == 0x80) + if ((txt[3] & 0xC0) == 0x80) + if ((txt[4] & 0xC0) == 0x80) + if ((txt[5] & 0xC0) == 0x80) + return (6); + return (1); + } + if (strcmp("SHIFT_JIS", p) == 0) + { + free(p); + if (*txt & 0x80) + return (2); + else + return (1); + } + free(p); + return (1); +} + +//ichikawa +int encode_quoted_printable (const char *str, const int length, + const char* charset, int (*is_encode)(const unsigned char), + int (*func)(const char *, size_t, void *), void *arg); +//ichikawa +int encode_base64 (const char *str, const int length, + const char* charset, int (*is_encode)(const unsigned char), + int (*func)(const char *, size_t, void *), void *arg); + +// ichikawa +/* Header line length SHOULD be less than 78 characters except CRLF */ +/* A multi-byte character MUST NOT split into encoded-words */ +/* Start and termination code MUST be included in each encoded-word, + typically in Asian 7-bit encoding (e.g iso-2022-*) */ +/* Some codings favor B encoding, instead of Q encoding */ +/* is_encode func is for decision which character is encoded in Q encoding */ +int rfc2047_encode_callback_new(const char *str, const int length, + const char *charset, const char *outgoing_charset, size_t *startpos, + int (*is_encode)(const unsigned char), + int (*func)(const char *, size_t, void *), void *arg) +{ +#define LWS "\n " /* LWS:'linear-white-space' (rfc2047) */ +int rc; +size_t i, l, mbl, run; +int (*encode_func) (const char *, const int, + const char*, int (*)(const unsigned char), + int (*)(const char *, size_t, void *), void *); + +//#if HAVE_UNICODE +#if HAVE_LIBUNICODE + if (outgoing_charset==NULL) + outgoing_charset=charset; +#else + outgoing_charset=charset; +#endif + /* choice encoding, B-encoding or Q-encoding */ + if (strcmp(outgoing_charset, "iso-2022-jp")==0 || + strcmp(outgoing_charset, "iso-8859-6")==0 || + strcmp(outgoing_charset, "iso-8859-7")==0 || + strcmp(outgoing_charset, "iso-8859-8")==0 || + strcmp(outgoing_charset, "tis-620")==0 || + strcmp(outgoing_charset, "euc-kr")==0 || + strcmp(outgoing_charset, "iso-2022-kr")==0 || + strcmp(outgoing_charset, "iso-2022-cn")==0 || + strcmp(outgoing_charset, "iso-2022-cn-ext")==0 || + strcmp(outgoing_charset, "gb2312")==0 || + strcmp(outgoing_charset, "hz-gb-2312")==0 || + strcmp(outgoing_charset, "big5")==0) + encode_func = encode_base64; + else + encode_func = encode_quoted_printable; + +//#if HAVE_UNICODE +#if HAVE_LIBUNICODE + + const struct unicode_info *src_chset= + unicode_find(charset); + const struct unicode_info *dst_chset= + unicode_find(outgoing_charset); + char *p, *q; +#endif + i=0; + run=0; + /* fetch first chracter */ + mbl = get_next_a_character_length(&str[i+run], charset); + run += mbl; + /* continue to scan the whole *str string */ + while ((i+run) <= length) + { + /* get length after charset translation and MIME encoding */ + l=0; +//#if HAVE_UNICODE +#if HAVE_LIBUNICODE + p=malloc(sizeof(char)*(run+3)); + strncpy(p,str+i,run); + p[run]=0; + q=unicode_xconvert(p, src_chset, dst_chset); + rc=(*encode_func)(q, strlen(q), outgoing_charset, + is_encode, &count_char, &l); + free(p); free(q); +#else + rc=(*encode_func)(str+i, run, outgoing_charset, + is_encode, &count_char, &l); +#endif + if(rc) return (rc); + + /* If it is over the limit of header line length */ + if (*startpos + l > 78) { + run -= mbl; /* back to safty length range */ + /* output charset translated, MIME-encoding string */ + if(run>0) + { +//#if HAVE_UNICODE +#if HAVE_LIBUNICODE + p=malloc(sizeof(char)*(run+3)); + strncpy(p,str+i,run); + p[run]=0; + q=unicode_xconvert(p, src_chset, dst_chset); + rc=(*encode_func)(q, strlen(q), outgoing_charset, + is_encode, func, arg); + free(p); free(q); +#else + rc=(*encode_func)(str+i, run, outgoing_charset, + is_encode, func, arg); +#endif + if(rc) return (rc); + i+=run; + run=0; + } + /* output linear-white-space */ + if ((rc=(*func)(LWS, strlen(LWS), arg)) != 0) + return (rc); + *startpos = 1; + } + /* fetch next chracter */ + mbl = get_next_a_character_length(&str[i+run], charset); + run += mbl; + } + /* output last line's encoded-word */ + run -= mbl; + if(run>0) + { +//#if HAVE_UNICODE +#if HAVE_LIBUNICODE + p=malloc(sizeof(char)*(run+3)); + strncpy(p,str+i,run); + p[run]=0; + q=unicode_xconvert(p, src_chset, dst_chset); + /* output string */ + rc=(*encode_func)(q, strlen(q), outgoing_charset, + is_encode, func, arg); + free(p); free(q); +#else + rc=(*encode_func)(str+i, run, outgoing_charset, + is_encode, func, arg); +#endif + if(rc) return (rc); + /* get length to shift startpos */ + l=0; +//#if HAVE_UNICODE +#if HAVE_LIBUNICODE + p=malloc(sizeof(char)*(run+3)); + strncpy(p,str+i,run); + p[run]=0; + q=unicode_xconvert(p, src_chset, dst_chset); + rc=(*encode_func)(q, strlen(q), outgoing_charset, + is_encode, &count_char, &l); + free(p); free(q); +#else + rc=(*encode_func)(str+i, run, outgoing_charset, + is_encode, &count_char, &l); +#endif + if(rc) return (rc); + *startpos += l; + + i+=run; + run=0; + } + return (0); +} + +//ichikawa +/* cf. RFC2047: section 5.3 */ +int is_phrase_q_encode (const unsigned char a) +{ + if (isalnum(a) || + a=='!' || a=='*' || a=='+' || a=='-' || a=='/') + return (0); + else + return (1); +} + +//ichikawa +int is_comment_q_encode (const unsigned char a) +{ + if ((a & 0x80) || a == '"' || + a == ' ' || a == '_' || a == '=' || a == '?') + return (1); + else + return (0); +} + +//ichikawa +int is_text_q_encode (const unsigned char a) +{ + if ((a & 0x80) || + a == ' ' || a == '_' || a == '=' || a == '?') + return (1); + else + return (0); +} + +//ichikawa +int encode_quoted_printable (const char *str, const int length, + const char* charset, int (*is_encode)(const unsigned char), + int (*func)(const char *, size_t, void *), void *arg) +{ +int i,rc; +char buf[3]; + + if ( (rc=(*func)("=?", 2, arg)) != 0 || + (rc=(*func)(charset, strlen(charset), arg)) != 0 || + (rc=(*func)("?Q?", 3, arg)) != 0) + return (rc); + for (i=0; i> 4) & 0x0F ]; + buf[2]=xdigit[ str[i] & 0x0F ]; + if ((rc=(*func)(buf, 3, arg)) != 0) + return (rc); + } + } + else + { + if ((rc=(*func)(str+i, 1, arg)) != 0) + return (rc); + } + } + if ((rc=(*func)("?=", 2, arg)) != 0) + return (rc); + return(0); +} + +//ichikawa +static const char encode64tab[]= +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +//ichikawa +/* is_encode will be NULL, will be unused */ +int encode_base64 (const char *str, const int length, + const char* charset, int (*is_encode)(const unsigned char), + int (*func)(const char *, size_t, void *), void *arg) +{ +int i,rc; +char buf[4]; +unsigned char a,b,c; + + if ( (rc=(*func)("=?", 2, arg)) != 0 || + (rc=(*func)(charset, strlen(charset), arg)) != 0 || + (rc=(*func)("?B?", 3, arg)) != 0) + return (rc); + for (i=0; i> 2 ]; + buf[1]=encode64tab[ ((a & 3 ) << 4) | (b >> 4)]; + buf[2]=encode64tab[ ((b & 15) << 2) | (c >> 6)]; + buf[3]=encode64tab[ c & 63 ]; + if (i + 1 >= length) buf[2]='='; + if (i + 2 >= length) buf[3]='='; + if ((rc=(*func)(buf, 4, arg)) != 0) + return (rc); + } + if ((rc=(*func)("?=", 2, arg)) != 0) + return (rc); + return(0); +} + diff -r -u sqwebmail-3.6.0-orig/rfc822/rfc2047.h sqwebmail-3.6.0/rfc822/rfc2047.h --- sqwebmail-3.6.0-orig/rfc822/rfc2047.h 2002-09-20 12:56:50.000000000 +0900 +++ sqwebmail-3.6.0/rfc822/rfc2047.h 2004-01-12 00:27:28.000000000 +0900 @@ -23,6 +23,9 @@ extern char *rfc2047_decode_simple(const char *text); extern char *rfc2047_decode_enhanced(const char *text, const char *mychset); +//ichikawa +extern char *rfc2047_decode_enhanced_new(const char *text, const char *mychset, + const char *outchset); /* ** If libunicode.a is available, like rfc2047_decode_enhanced, but attempt to @@ -64,7 +67,10 @@ */ char *rfc2047_encode_str(const char *str, const char *charset); - + //ichikawa +char *rfc2047_encode_str_new(const char *str, const char *charset, + const char *outgoing_charset); + /* ** If you can live with the encoded text being generated on the fly, use ** rfc2047_encode_callback, which calls a callback function, instead of @@ -73,6 +79,17 @@ int rfc2047_encode_callback(const char *str, const char *charset, int (*func)(const char *, size_t, void *), void *arg); + //ichikawa +int rfc2047_encode_callback_new(const char *str, const int length, + const char *charset, const char *outgoing_charset, size_t *startpos, + int (*is_encode)(const unsigned char), + int (*func)(const char *, size_t, void *), void *arg); +int rfc2047_addr_encode_callback(const char *str, const char *charset, + const char *outgoing_charset, + int (*func)(const char *, size_t, void *), void *arg); +int rfc2047_text_encode_callback(const char *str, const char *charset, + const char *outgoing_charset, + int (*func)(const char *, size_t, void *), void *arg); /* ** rfc2047_encode_header allocates a buffer, and MIME-encodes an RFC822 header @@ -80,6 +97,12 @@ */ char *rfc2047_encode_header(const struct rfc822a *a, const char *charset); +//ichikawa +char *rfc2047_encode_header_new(const struct rfc822a *a, + const char *charset, const char *outgoing_charset); + +//ichikawa +int get_next_a_character_length (const char *txt, const char *chset); #ifdef __cplusplus } diff -r -u sqwebmail-3.6.0-orig/rfc822/rfc822.c sqwebmail-3.6.0/rfc822/rfc822.c --- sqwebmail-3.6.0-orig/rfc822/rfc822.c 2002-03-05 10:22:20.000000000 +0900 +++ sqwebmail-3.6.0/rfc822/rfc822.c 2003-12-29 01:24:53.000000000 +0900 @@ -124,8 +124,12 @@ case ']': case '%': case '!': +//ichikawa +// for rfc2047 compliance +#if 1 //mime is disable case '?': case '=': +#endif case '/': if ( (*p == '<' && inbracket) || @@ -175,8 +179,15 @@ tokp->ptr=p; tokp->len=0; } +//ichikawa +// for rfc2047 compliance +#if 1 while (*p && !isspace((int)(unsigned char)*p) && strchr( "<>@,;:.[]()%!\"\\?=/", *p) == 0) +#else //mime + while (*p && !isspace((int)(unsigned char)*p) && strchr( + "<>@,;:.[]()%!\"\\/", *p) == 0) +#endif { if (tokp) ++tokp->len; ++p; @@ -276,9 +287,19 @@ If it consists exclusively of atoms, leave them alone. Else, make them all a quoted string. */ + //ichikawa + // for rfc2047 compliance +#if 1 //mime + for (j=0; jname))!=0) { - char *q= (*decode_func)(p, chset); + char *q= (*decode_func)(p, chset, outgoing_chset); char *r; for (r=q; r && *r; r++) @@ -533,7 +556,8 @@ if (decode_func && (p=rfc822_gettok(addrs->name)) != 0) { - char *q= (*decode_func)(p, chset); + char *q= (*decode_func)(p, chset, + outgoing_chset); char *r; for (r=q; r && *r; r++) diff -r -u sqwebmail-3.6.0-orig/rfc822/rfc822.h sqwebmail-3.6.0/rfc822/rfc822.h --- sqwebmail-3.6.0-orig/rfc822/rfc822.h 2003-03-17 02:25:12.000000000 +0900 +++ sqwebmail-3.6.0/rfc822/rfc822.h 2003-11-02 16:25:04.000000000 +0900 @@ -123,9 +123,10 @@ /* rfc822_print_common is an internal function */ +//ichikawa void rfc822_print_common(const struct rfc822a *a, - char *(*decode_func)(const char *, const char *), - const char *chset, + char *(*decode_func)(const char *, const char *, const char *), + const char *chset, const char *outgoing_chset, void (*print_func)(char, void *), void (*print_separator)(const char *, void *), void *); diff -r -u sqwebmail-3.6.0-orig/sqwebmail/folder.c sqwebmail-3.6.0/sqwebmail/folder.c --- sqwebmail-3.6.0-orig/sqwebmail/folder.c 2003-08-13 00:16:29.000000000 +0900 +++ sqwebmail-3.6.0/sqwebmail/folder.c 2004-01-12 12:50:05.000000000 +0900 @@ -1036,6 +1036,10 @@ int n; int fd; + //ichikawa + // to read message + //sleep(20); + if (*cgi("addnick")) { const char *name=cgi("newname"); @@ -2382,8 +2386,15 @@ if (cb && strcasecmp(cb, "xdraft") == 0) { preview_start(); +//ichikawa +#if HAVE_SQWEBMAIL_UNICODE + rfc2045_decodetextmimesection(fileno(fp), rfc, + sqwebmail_content_charset, + &preview_callback, NULL); +#else rfc2045_decodemimesection(fileno(fp), rfc, &preview_callback, NULL); +#endif preview_end(); return; } diff -r -u sqwebmail-3.6.0-orig/sqwebmail/newmsg.c sqwebmail-3.6.0/sqwebmail/newmsg.c --- sqwebmail-3.6.0-orig/sqwebmail/newmsg.c 2003-06-18 00:38:37.000000000 +0900 +++ sqwebmail-3.6.0/sqwebmail/newmsg.c 2004-01-12 15:24:08.000000000 +0900 @@ -76,7 +76,13 @@ { char *s; +//ichikawa +#if 1 //mine + s=rfc2047_decode_enhanced_new(val, sqwebmail_content_charset, + sqwebmail_content_charset); +#else s=rfc2047_decode_simple(val); +#endif if (!s) enomem(); output_attrencoded(s); free(s); @@ -303,9 +309,18 @@ q=rfc2045_searchcontenttype(p, "text/plain"); +//ichikawa +#if HAVE_SQWEBMAIL_UNICODE + if (q) + rfc2045_decodetextmimesection(fileno(fp), q, + sqwebmail_content_charset, + &show_textarea, NULL); +#else if (q) rfc2045_decodemimesection(fileno(fp), q, &show_textarea, NULL); +#endif + rfc2045_free(p); } diff -r -u sqwebmail-3.6.0-orig/sqwebmail/newmsg_create.c sqwebmail-3.6.0/sqwebmail/newmsg_create.c --- sqwebmail-3.6.0-orig/sqwebmail/newmsg_create.c 2003-07-10 04:19:16.000000000 +0900 +++ sqwebmail-3.6.0/sqwebmail/newmsg_create.c 2004-01-18 20:45:08.000000000 +0900 @@ -38,6 +38,12 @@ extern const char *rfc822_mkdt(time_t); extern const char *sqwebmail_content_charset; +// ichikawa +extern const char *sqwebmail_outgoing_charset; +//#if HAVE_UNICODE +#if HAVE_SQWEBMAIL_UNICODE +#include "unicode/unicode.h" +#endif extern const char *sqwebmail_content_language; int newdraftfd; @@ -110,7 +116,10 @@ if (!isrfc822addr) { - s=rfc2047_encode_str(p, sqwebmail_content_charset); + //ichikawa + s=rfc2047_encode_str_new(p, sqwebmail_content_charset, + sqwebmail_outgoing_charset); + //s=rfc2047_encode_str(p, sqwebmail_content_charset); } else { @@ -127,8 +136,15 @@ { if ((a=rfc822a_alloc(t)) != 0) { + //ichikawa +#if 1 + s=rfc2047_encode_header_new(a, + sqwebmail_content_charset, + sqwebmail_outgoing_charset); +#else s=rfc2047_encode_header(a, sqwebmail_content_charset); +#endif rfc822a_free(a); } rfc822t_free(t); @@ -379,11 +395,20 @@ charset=sqwebmail_content_charset; } +//ichikawa +#if HAVE_SQWEBMAIL_UNICODE //mime + maildir_writemsgstr(newdraftfd, "Mime-Version: 1.0\n" + "Content-Type: text/plain; format=xdraft;" + " charset=\""); + maildir_writemsgstr(newdraftfd, sqwebmail_outgoing_charset); + maildir_writemsgstr(newdraftfd, "\"\n"); +#else maildir_writemsgstr(newdraftfd, "Mime-Version: 1.0\n" "Content-Type: text/plain; format=xdraft;" " charset=\""); maildir_writemsgstr(newdraftfd, charset); maildir_writemsgstr(newdraftfd, "\"\n"); +#endif if (rfcp) rfc2045_free(rfcp); @@ -403,6 +428,19 @@ for (i=j=0; buf[i]; i++) if (buf[i] != '\r') buf[j++]=buf[i]; +// ichikawa +#if HAVE_SQWEBMAIL_UNICODE + char *encode_buf; + const struct unicode_info *src_chset= + unicode_find(sqwebmail_content_charset); + const struct unicode_info *dst_chset= + unicode_find(sqwebmail_outgoing_charset); + encode_buf=unicode_xconvert(buf, src_chset, dst_chset); + free(buf); + buf=encode_buf; + j=strlen(buf); +#endif + /* Trim excessive trailing empty lines */ while (j > 4 && strncmp(buf+j-3, "\n\n\n", 3) == 0) @@ -563,7 +601,13 @@ { struct lookup_buffers *lookup_buffer_list=0; int rc; +//ichikawa +#if 1 //mime +char *s=rfc2047_decode_enhanced_new(value, sqwebmail_content_charset, + sqwebmail_content_charset); +#else char *s=strdup(value); +#endif if (!s) enomem(); rc=lookup_addressbook_do(header, s, &lookup_buffer_list); @@ -657,8 +701,9 @@ maildir_writemsgstr(newdraftfd, "Content-Type: text/plain;" " format=flowed; charset=\""); + // ichikawa maildir_writemsgstr(newdraftfd, - sqwebmail_content_charset); + sqwebmail_outgoing_charset); maildir_writemsgstr(newdraftfd, "\"\n"); continue; } diff -r -u sqwebmail-3.6.0-orig/sqwebmail/sqwebmail.c sqwebmail-3.6.0/sqwebmail/sqwebmail.c --- sqwebmail-3.6.0-orig/sqwebmail/sqwebmail.c 2003-08-10 08:11:09.000000000 +0900 +++ sqwebmail-3.6.0/sqwebmail/sqwebmail.c 2004-01-18 18:41:49.000000000 +0900 @@ -97,6 +97,8 @@ const char *sqwebmail_content_locale; const char *sqwebmail_content_ispelldict; const char *sqwebmail_content_charset; +// ichikawa +const char *sqwebmail_outgoing_charset="iso-2022-jp"; static int noimages=0; @@ -765,6 +767,11 @@ pid_t pid= -1; #endif + // ichikawa + //if (strcmp(formname, "readmsg.html") == 0) + //if (strcmp(formname, "newmsg.html") == 0) + //sleep(20); + noimages= access(NOIMAGES, 0) == 0; f=do_open_form(formname, 1); @@ -891,6 +898,9 @@ { int c, c2, c3; + // ichikawa + //sleep(20); + while ((c=getc(f)) >= 0) { char kw[64]; @@ -1758,6 +1768,10 @@ if (strcmp(formname, "donewmsg") == 0) { + // ichikawa + // to send + sleep(30); + newmsg_do(sqwebmail_folder); return; } @@ -2193,6 +2207,9 @@ { int rc; +// ichikawa +//sleep(20); + /* If we are running setuid non-root, change our real gid/uid too */ if (getegid()) setgid(getegid()); if (geteuid()) setuid(geteuid());