Commit b3e94c4e authored by rswindell's avatar rswindell
Browse files

New QWK setting: Include UTF-8 chars. When off/false (the default), UTF-8

characters in message headers and body text will be converted to CP437.
Also include a new field in HEADERS.DAT: utf8 = true/false to indicate that
the message headers and body text contain UTF-8 encoding (not CP437).
parent 9532f364
......@@ -139,7 +139,7 @@ const char* sbbs_t::msghdr_field(const smbmsg_t* msg, const char* str, char* buf
if(msg == NULL || !(msg->hdr.auxattr & MSG_HFIELDS_UTF8))
return str;
if(can_utf8 && term_supports(UTF8))
if(can_utf8)
return str;
if(buf == NULL)
......
......@@ -35,6 +35,7 @@
#include "sbbs.h"
#include "qwk.h"
#include "utf8.h"
#define MAX_MSGNUM 0x7FFFFFUL // only 7 (decimal) digits allowed for msg num
......@@ -46,7 +47,10 @@
ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, smb_t* smb
, int conf, FILE* hdrs, FILE* voting)
{
char str[512],from[512],to[512],ch=0,tear=0,tearwatch=0,*buf,*p;
char str[512],ch=0,tear=0,tearwatch=0,*buf,*p;
char to[512] = "";
char from[512] = "";
char subj[512] = "";
char msgid[256];
char reply_id[256];
char tmp[512];
......@@ -61,6 +65,13 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, smb_t* smb
get_msgid(&cfg, subnum, msg, msgid, sizeof(msgid));
offset=(long)ftell(qwk_fp);
if(msg->to != NULL)
SAFECOPY(to, msghdr_field(msg, msg->to, NULL, mode&QM_UTF8));
if(msg->from != NULL)
SAFECOPY(from, msghdr_field(msg, msg->from, NULL, mode&QM_UTF8));
if(msg->subj != NULL)
SAFECOPY(subj, msghdr_field(msg, msg->subj, NULL, mode&QM_UTF8));
if(msg->hdr.type != SMB_MSG_TYPE_NORMAL) {
if(voting == NULL)
return 0;
......@@ -78,6 +89,8 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, smb_t* smb
unsigned comments = 0;
unsigned answers = 0;
fprintf(voting, "[poll:%s]\n", msgid);
fprintf(voting , "Utf8 = %s\n"
,((msg->hdr.auxattr & MSG_HFIELDS_UTF8) && (mode&QM_UTF8)) ? "true" : "false");
if(msg->hdr.votes)
fprintf(voting, "MaxVotes = %hd\n", msg->hdr.votes);
if(msg->hdr.auxattr&POLL_RESULTS_MASK)
......@@ -94,8 +107,8 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, smb_t* smb
fprintf(voting, "[close:%s]\n", msgid);
break;
}
if(msg->subj && *msg->subj)
fprintf(voting, "%s: %s\n",smb_hfieldtype(SUBJECT), msg->subj);
if(subj[0])
fprintf(voting, "%s: %s\n",smb_hfieldtype(SUBJECT), subj);
if((p = get_replyid(&cfg, smb, msg, reply_id, sizeof(reply_id))) != NULL)
fprintf(voting, "%s: %s\n", smb_hfieldtype(RFC822REPLYID), p);
/* Time/Date/Zone info */
......@@ -108,7 +121,7 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, smb_t* smb
);
/* SENDER */
fprintf(voting, "%s: %s\n", smb_hfieldtype(SENDER), msg->from);
fprintf(voting, "%s: %s\n", smb_hfieldtype(SENDER), from);
if(msg->from_net.type)
fprintf(voting, "%s: %s\n", smb_hfieldtype(SENDERNETADDR), smb_netaddrstr(&msg->from_net, tmp));
fprintf(voting, "Conference: %u\n", conf);
......@@ -117,6 +130,10 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, smb_t* smb
else if(hdrs!=NULL) {
fprintf(hdrs,"[%lx]\n",offset);
fprintf(voting , "Utf8 = %s\n"
,((smb_msg_is_utf8(msg) || (msg->hdr.auxattr & MSG_HFIELDS_UTF8)) && (mode&QM_UTF8))
? "true" : "false");
/* Message-IDs */
fprintf(hdrs,"%s: %s\n", smb_hfieldtype(RFC822MSGID), msgid);
if((p = get_replyid(&cfg, smb, msg, reply_id, sizeof(reply_id))) != NULL)
......@@ -151,7 +168,7 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, smb_t* smb
);
/* SENDER */
fprintf(hdrs,"%s: %s\n",smb_hfieldtype(SENDER),msg->from);
fprintf(hdrs,"%s: %s\n",smb_hfieldtype(SENDER), from);
if(msg->from_net.type)
fprintf(hdrs,"%s: %s\n",smb_hfieldtype(SENDERNETADDR),smb_netaddrstr(&msg->from_net,tmp));
if((p=(char*)smb_get_hfield(msg,hfield_type=SENDERIPADDR,NULL))!=NULL)
......@@ -176,10 +193,10 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, smb_t* smb
fprintf(hdrs,"Reply-To: %s\n",p); /* use original RFC822 header field */
/* SUBJECT */
fprintf(hdrs,"%s: %s\n",smb_hfieldtype(SUBJECT),msg->subj);
fprintf(hdrs,"%s: %s\n",smb_hfieldtype(SUBJECT), subj);
/* RECIPIENT */
fprintf(hdrs,"%s: %s\n",smb_hfieldtype(RECIPIENT),msg->to);
fprintf(hdrs,"%s: %s\n",smb_hfieldtype(RECIPIENT), to);
if(msg->to_net.type!=NET_NONE && subnum==INVALID_SUB)
fprintf(hdrs,"%s: %s\n",smb_hfieldtype(RECIPIENTNETADDR),smb_netaddrstr(&msg->to_net,tmp));
......@@ -242,14 +259,15 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, smb_t* smb
return(0);
char qwk_newline = QWK_NEWLINE;
if(smb_msg_is_utf8(msg))
qwk_newline = '\n';
if(smb_msg_is_utf8(msg)) {
if(mode&QM_UTF8)
qwk_newline = '\n';
else
utf8_normalize_str(buf);
}
fprintf(qwk_fp,"%*s",QWK_BLOCK_LEN,""); /* Init header to space */
SAFECOPY(from,msg->from);
SAFECOPY(to,msg->to);
if(msg->hdr.type == SMB_MSG_TYPE_NORMAL) {
/* QWKE compatible kludges */
if(msg->from_net.addr && (uint)subnum==INVALID_SUB && !(mode&QM_TO_QNET)) {
......@@ -297,8 +315,8 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, smb_t* smb
else
SAFECOPY(to,msg->to);
}
if((mode&QM_EXT) && strlen(msg->subj) > QWK_HFIELD_LEN)
size+=fprintf(qwk_fp,"Subject: %.128s%c", msg->subj, qwk_newline);
if((mode&QM_EXT) && strlen(subj) > QWK_HFIELD_LEN)
size+=fprintf(qwk_fp,"Subject: %.128s%c", subj, qwk_newline);
if(msg->from_net.type==NET_QWK && mode&QM_VIA && !msg->forwarded)
size+=fprintf(qwk_fp,"@VIA: %s%c"
......@@ -535,7 +553,7 @@ ulong sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, long mode, smb_t* smb
,tmp /* date and time */
,to /* To: */
,from /* From: */
,msg->subj /* Subject */
,subj /* Subject */
,nulstr /* Password */
,msg->hdr.thread_back&MAX_MSGNUM /* Message Re: Number */
,(size/QWK_BLOCK_LEN)+1 /* Number of blocks */
......
......@@ -105,8 +105,7 @@ bool sbbs_t::pack_qwk(char *packet, ulong *msgcnt, bool prepack)
mode|=QM_VIA;
if(useron.qwk&QWK_MSGID)
mode|=QM_MSGID;
if(useron.qwk&QWK_EXT)
mode|=QM_EXT;
mode |= useron.qwk&(QWK_EXT | QWK_UTF8);
(*msgcnt)=0L;
if(/* !prepack && */ !(useron.qwk&QWK_NOCTRL)) {
......
......@@ -149,7 +149,7 @@ bool sbbs_t::pack_rep(uint hubnum)
}
mode = QM_TO_QNET|QM_REP;
mode |= (cfg.qhub[hubnum]->misc&(QHUB_EXT|QHUB_CTRL_A));
mode |= (cfg.qhub[hubnum]->misc&(QHUB_EXT | QHUB_CTRL_A | QHUB_UTF8));
/* For an unclear reason, kludge lines (including @VIA and @TZ) were not included in NetMail previously */
if(!(cfg.qhub[hubnum]->misc&QHUB_NOHEADERS)) mode|=(QM_VIA|QM_TZ|QM_MSGID|QM_REPLYTO);
msgtoqwk(&msg, rep, mode, &smb, /* confnum: */0, hdrs);
......@@ -223,7 +223,7 @@ bool sbbs_t::pack_rep(uint hubnum)
}
mode = cfg.qhub[hubnum]->mode[i]|QM_TO_QNET|QM_REP;
mode |= (cfg.qhub[hubnum]->misc&(QHUB_EXT|QHUB_CTRL_A));
mode |= (cfg.qhub[hubnum]->misc&(QHUB_EXT | QHUB_CTRL_A | QHUB_UTF8));
if(!(cfg.qhub[hubnum]->misc&QHUB_NOHEADERS)) mode|=(QM_VIA|QM_TZ|QM_MSGID|QM_REPLYTO);
if(msg.from_net.type!=NET_QWK)
mode|=QM_TAGLINE;
......
......@@ -91,23 +91,23 @@ bool sbbs_t::postmsg(uint subnum, long wm_mode, smb_t* resmb, smbmsg_t* remsg)
uint reason;
if(remsg) {
SAFECOPY(title, msghdr_field(remsg, remsg->subj, NULL, /* UTF8: */true));
SAFECOPY(title, msghdr_field(remsg, remsg->subj, NULL, term_supports(UTF8)));
if(remsg->hdr.attr&MSG_ANONYMOUS)
SAFECOPY(from,text[Anonymous]);
else
SAFECOPY(from, msghdr_field(remsg, remsg->from, NULL, /* UTF8: */true));
SAFECOPY(from, msghdr_field(remsg, remsg->from, NULL, term_supports(UTF8)));
// If user posted this message, reply to the original recipient again
if(remsg->to != NULL
&& ((remsg->from_ext != NULL && atoi(remsg->from_ext)==useron.number)
|| stricmp(useron.alias,remsg->from) == 0 || stricmp(useron.name,remsg->from) == 0))
SAFECOPY(touser, msghdr_field(remsg, remsg->to, NULL, /* UTF8: */true));
SAFECOPY(touser, msghdr_field(remsg, remsg->to, NULL, term_supports(UTF8)));
else
SAFECOPY(touser,from);
msgattr=(ushort)(remsg->hdr.attr&MSG_PRIVATE);
sprintf(top,text[RegardingByToOn]
,title
,from
,msghdr_field(remsg, remsg->to, NULL, /* UTF8: */true)
,msghdr_field(remsg, remsg->to, NULL, term_supports(UTF8))
,timestr(remsg->hdr.when_written.time)
,smb_zonestr(remsg->hdr.when_written.zone,NULL));
if(remsg->tags != NULL)
......
......@@ -483,10 +483,12 @@ void sbbs_t::qwk_sec()
,useron.qwk&QWK_VIA ? text[Yes]:text[No]);
bprintf(text[QWKSettingsMsgID]
,useron.qwk&QWK_MSGID ? text[Yes]:text[No]);
bprintf(text[QWKSettingsUtf8]
,useron.qwk&QWK_UTF8 ? text[Yes]:text[No]);
bprintf(text[QWKSettingsExtended]
,useron.qwk&QWK_EXT ? text[Yes]:text[No]);
bputs(text[QWKSettingsWhich]);
ch=(char)getkeys("AEDFHIOPQTYMNCXZV",0);
ch=(char)getkeys("AEDFHIOPQTUYMNCXZV",0);
if(sys_status&SS_ABORT || !ch || ch=='Q' || !online)
break;
switch(ch) {
......@@ -555,6 +557,9 @@ void sbbs_t::qwk_sec()
case 'X': /* QWKE */
useron.qwk^=QWK_EXT;
break;
case 'U':
useron.qwk^=QWK_UTF8;
break;
}
putuserrec(&cfg,useron.number,U_QWK,8,ultoa(useron.qwk,str,16));
}
......
......@@ -50,6 +50,7 @@
#define QM_MSGID (1<<10) /* Include @MSGID and @REPLY kludges */
#define QM_REPLYTO (1<<11) /* Include @REPLYTO kludge */
#define QM_EXT (1<<13) /* QWK Extended (QWKE) mode (same as QWK_EXT and QHUB_EXT) */
#define QM_UTF8 (1<<18) /* Include UTF-8 characters */
float ltomsbin(long val);
bool route_circ(char *via, char *id);
......
......@@ -436,6 +436,7 @@ typedef enum { /* Values for xtrn_t.event */
#define QWK_MSGID (1L<<14) /* Include "@MSGID" in msgs */
#define QWK_HEADERS (1L<<16) /* Include HEADERS.DAT file */
#define QWK_VOTING (1L<<17) /* Include VOTING.DAT */
#define QWK_UTF8 (1L<<18) /* Include UTF-8 characters */
#define QWK_DEFAULT (QWK_FILES|QWK_ATTACH|QWK_EMAIL|QWK_DELMAIL)
......@@ -447,6 +448,7 @@ typedef enum { /* Values for xtrn_t.event */
#define QHUB_NOKLUDGES (1<<14) /* Don't include @-kludges */
#define QHUB_NOHEADERS (1<<16) /* Don't include HEADERS.DAT */
#define QHUB_NOVOTING (1<<17) /* Don't include VOTING.DAT */
#define QHUB_UTF8 (1<<18) /* Include UTF-8 characters */
/* Bits in user.chat */
#define CHAT_ECHO (1<<0) /* Multinode chat echo */
......
......@@ -837,6 +837,7 @@ enum {
,Utf8TerminalQ
,MsgCarbonCopyList
,LoggingOn
,QWKSettingsUtf8
,TOTAL_TEXT
};
......
......@@ -116,9 +116,9 @@ const char * const text_defaults[TOTAL_TEXT]={
,"\x01\x6e\x0d\x0a\x4e\x6f\x20\x6d\x61\x69\x6c\x20\x6f\x6e\x20\x73\x79\x73\x74\x65\x6d\x2e\x0d\x0a" // 063 NoMailOnSystem
,"\x01\x6e\x0d\x0a\x01\x63\xfe\x20\x01\x68\x01\x62\x52\x65\x61\x64\x69\x6e\x67\x20\x41\x6c\x6c\x20\x45\x2d\x6d\x61\x69\x6c\x20\x01"
"\x6e\x01\x63\xfe\x20\x01\x68\x01\x62\x28\x01\x77\x25\x75\x20\x01\x62\x6f\x66\x20\x01\x77\x25\x75\x01\x62\x29\x3a\x20\x01\x6e" // 064 ReadingAllMail
,"\x01\x5f\x0d\x0a\x01\x71\x01\x67\x01\x68\x20\x20\x20\x20\x20\x20\x46\x72\x6f\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x20\x20\x20\x20\x20\x20\x20\x54\x6f\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x41\x20"
"\x53\x75\x62\x6a\x65\x63\x74\x0d\x0a\x01\x6e" // 065 MailOnSystemLstHdr
,"\x01\x5f\x0d\x0a\x01\x67\x01\x68\x20\x20\x20\x20\x20\x20\x46\x72\x6f\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x20\x20\x20\x20\x20\x54\x6f\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x41\x20\x53\x75"
"\x62\x6a\x65\x63\x74\x0d\x0a\x01\x6e" // 065 MailOnSystemLstHdr
,"\x01\x67\x01\x68\x25\x35\x64\x01\x6e\x01\x67\x20\x25\x2d\x32\x32\x2e\x32\x32\x73\x20\x25\x2d\x32\x32\x2e\x32\x32\x73\x20\x01\x68"
"\x25\x63\x01\x6e\x01\x67\x20\x25\x73\x0d\x0a" // 066 MailOnSystemLstFmt
,"\x01\x2d\x0d\x0a\x01\x63\x25\x2d\x31\x35\x2e\x31\x35\x73\x20\x01\x79\x01\x68\x25\x2d\x34\x34\x2e\x34\x34\x73\x20\x01\x6e\x01\x63"
......@@ -1362,4 +1362,6 @@ const char * const text_defaults[TOTAL_TEXT]={
,"\x0d\x0a\xb3\x20\x01\x62\x43\x43\x20\x20\x01\x6e\x01\x62\x3a\x20\x01\x68\x01\x63\x25\x2e\x37\x30\x73" // 825 MsgCarbonCopyList
,"\x01\x6e\x01\x68\x4c\x6f\x67\x67\x69\x6e\x67\x20\x6f\x6e\x20\x74\x6f\x20\x40\x42\x42\x53\x40\x20\x61\x73\x20\x40\x41\x4c\x49\x41"
"\x53\x40\x20\x40\x45\x4c\x4c\x49\x50\x53\x49\x53\x40\x01\x6e\x0d\x0a\x40\x52\x45\x53\x45\x54\x50\x41\x55\x53\x45\x40" // 826 LoggingOn
,"\x01\x6e\x01\x62\x5b\x01\x68\x01\x77\x55\x01\x6e\x01\x62\x5d\x20\x01\x68\x49\x6e\x63\x6c\x75\x64\x65\x20\x55\x54\x46\x2d\x38\x20"
"\x43\x68\x61\x72\x61\x63\x74\x65\x72\x73\x20\x20\x20\x20\x20\x01\x6e\x01\x62\x3a\x20\x01\x63\x25\x73\x0d\x0a" // 827 QWKSettingsUtf8
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment