Skip to content
Snippets Groups Projects
Commit a64ec5d5 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Add "word-wrap" option for QWK packet creation

Some BBS programs (e.g. Synchronet v2) or possibly old offline message readers
don't deal well with long-line messages. So add a per-user option to word/line
wrap message text.

Addresses issue (feature request) #428
Thanks for the reminder fusion @ CFBBS!
parent c7363587
No related branches found
No related tags found
No related merge requests found
Pipeline #6062 passed
...@@ -1058,3 +1058,4 @@ ...@@ -1058,3 +1058,4 @@
"\1n\1b[\1h\1wI\1n\1b] \1h%-29s\1n\1b: \1c%s\r\n" 872 UserDefaultsLanguage "\1n\1b[\1h\1wI\1n\1b] \1h%-29s\1n\1b: \1c%s\r\n" 872 UserDefaultsLanguage
"*" 873 PasswordChar "*" 873 PasswordChar
" via sftp" 874 NodeConnectionSFTP " via sftp" 874 NodeConnectionSFTP
"\1n\1b[\1h\1wW\1n\1b] \1hWord-wrap Message Text \1n\1b: \1c%s\r\n" 875 QWKSettingsWrapText
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "qwk.h" #include "qwk.h"
#include "utf8.h" #include "utf8.h"
#include "cp437defs.h" #include "cp437defs.h"
#include "wordwrap.h"
#define MAX_MSGNUM 0x7FFFFFUL // only 7 (decimal) digits allowed for msg num #define MAX_MSGNUM 0x7FFFFFUL // only 7 (decimal) digits allowed for msg num
...@@ -246,14 +247,24 @@ int sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, int mode, smb_t* smb ...@@ -246,14 +247,24 @@ int sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, int mode, smb_t* smb
if(!buf) if(!buf)
return -2; return -2;
bool is_utf8 = false;
char qwk_newline = QWK_NEWLINE; char qwk_newline = QWK_NEWLINE;
if(smb_msg_is_utf8(msg) || (msg->hdr.auxattr & MSG_HFIELDS_UTF8)) { if(smb_msg_is_utf8(msg) || (msg->hdr.auxattr & MSG_HFIELDS_UTF8)) {
if(mode&QM_UTF8) if(mode&QM_UTF8) {
qwk_newline = '\n'; qwk_newline = '\n';
else is_utf8 = true;
} else
utf8_to_cp437_inplace(buf); utf8_to_cp437_inplace(buf);
} }
if(mode & QM_WORDWRAP) {
int org_cols = msg->columns ? msg->columns : 80;
int new_cols = useron.cols ? useron.cols : cols ? cols : 80;
char* wrapped = ::wordwrap(buf, new_cols - 1, org_cols - 1, /* handle_quotes */true, is_utf8);
if(wrapped != NULL) {
free(buf);
buf = wrapped;
}
}
fprintf(qwk_fp,"%*s",QWK_BLOCK_LEN,""); /* Init header to space */ fprintf(qwk_fp,"%*s",QWK_BLOCK_LEN,""); /* Init header to space */
if(msg->hdr.type == SMB_MSG_TYPE_NORMAL) { if(msg->hdr.type == SMB_MSG_TYPE_NORMAL) {
......
...@@ -292,3 +292,8 @@ LOAD_CFG_OBJS = \ ...@@ -292,3 +292,8 @@ LOAD_CFG_OBJS = \
$(OBJODIR)/ars$(OFILE) \ $(OBJODIR)/ars$(OFILE) \
$(OBJODIR)/nopen$(OFILE) $(OBJODIR)/nopen$(OFILE)
TEXTGEN_OBJS = $(OBJODIR)/textgen$(OFILE) \
$(OBJODIR)/getctrl$(OFILE) \
$(OBJODIR)/str_util$(OFILE)
...@@ -112,7 +112,7 @@ bool sbbs_t::pack_qwk(char *packet, uint *msgcnt, bool prepack) ...@@ -112,7 +112,7 @@ bool sbbs_t::pack_qwk(char *packet, uint *msgcnt, bool prepack)
mode|=QM_VIA; mode|=QM_VIA;
if(useron.qwk&QWK_MSGID) if(useron.qwk&QWK_MSGID)
mode|=QM_MSGID; mode|=QM_MSGID;
mode |= useron.qwk&(QWK_EXT | QWK_UTF8); mode |= useron.qwk&(QWK_EXT | QWK_UTF8 | QWK_WORDWRAP);
(*msgcnt)=0L; (*msgcnt)=0L;
if(/* !prepack && */ !(useron.qwk&QWK_NOCTRL)) { if(/* !prepack && */ !(useron.qwk&QWK_NOCTRL)) {
......
...@@ -475,12 +475,15 @@ void sbbs_t::qwk_sec() ...@@ -475,12 +475,15 @@ void sbbs_t::qwk_sec()
add_hotspot('U'); add_hotspot('U');
bprintf(text[QWKSettingsUtf8] bprintf(text[QWKSettingsUtf8]
,useron.qwk&QWK_UTF8 ? text[Yes]:text[No]); ,useron.qwk&QWK_UTF8 ? text[Yes]:text[No]);
add_hotspot('W');
bprintf(text[QWKSettingsWrapText]
,useron.qwk&QWK_WORDWRAP ? text[Yes]:text[No]);
add_hotspot('X'); add_hotspot('X');
bprintf(text[QWKSettingsExtended] bprintf(text[QWKSettingsExtended]
,useron.qwk&QWK_EXT ? text[Yes]:text[No]); ,useron.qwk&QWK_EXT ? text[Yes]:text[No]);
bputs(text[QWKSettingsWhich]); bputs(text[QWKSettingsWhich]);
add_hotspot('Q'); add_hotspot('Q');
ch=(char)getkeys("AEDFHIOPQTUYMNCXZV",0); ch=(char)getkeys("AEDFHIOPQTUYMNCXZVW",0);
if(sys_status&SS_ABORT || !ch || ch=='Q' || !online) if(sys_status&SS_ABORT || !ch || ch=='Q' || !online)
break; break;
switch(ch) { switch(ch) {
...@@ -555,12 +558,15 @@ void sbbs_t::qwk_sec() ...@@ -555,12 +558,15 @@ void sbbs_t::qwk_sec()
case 'Y': /* Yourself */ case 'Y': /* Yourself */
useron.qwk^=QWK_BYSELF; useron.qwk^=QWK_BYSELF;
break; break;
case 'X': /* QWKE */
useron.qwk^=QWK_EXT;
break;
case 'U': case 'U':
useron.qwk^=QWK_UTF8; useron.qwk^=QWK_UTF8;
break; break;
case 'W':
useron.qwk^=QWK_WORDWRAP;
break;
case 'X': /* QWKE */
useron.qwk^=QWK_EXT;
break;
} }
putuserqwk(useron.number, useron.qwk); putuserqwk(useron.number, useron.qwk);
} }
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#define QM_REPLYTO (1<<11) /* Include @REPLYTO kludge */ #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_EXT (1<<13) /* QWK Extended (QWKE) mode (same as QWK_EXT and QHUB_EXT) */
#define QM_UTF8 (1<<18) /* Include UTF-8 characters */ #define QM_UTF8 (1<<18) /* Include UTF-8 characters */
#define QM_WORDWRAP (1<<19) /* Word-wrap message text */
float ltomsbin(int32_t val); float ltomsbin(int32_t val);
bool route_circ(char *via, char *id); bool route_circ(char *via, char *id);
......
...@@ -437,6 +437,7 @@ typedef enum { /* Values for xtrn_t.event */ ...@@ -437,6 +437,7 @@ typedef enum { /* Values for xtrn_t.event */
#define QWK_HEADERS (1<<16) /* Include HEADERS.DAT file */ #define QWK_HEADERS (1<<16) /* Include HEADERS.DAT file */
#define QWK_VOTING (1<<17) /* Include VOTING.DAT */ #define QWK_VOTING (1<<17) /* Include VOTING.DAT */
#define QWK_UTF8 (1<<18) /* Include UTF-8 characters */ #define QWK_UTF8 (1<<18) /* Include UTF-8 characters */
#define QWK_WORDWRAP (1<<19) /* Word-wrap message text */
#define QWK_DEFAULT (QWK_FILES|QWK_ATTACH|QWK_EMAIL|QWK_DELMAIL) #define QWK_DEFAULT (QWK_FILES|QWK_ATTACH|QWK_EMAIL|QWK_DELMAIL)
......
...@@ -142,6 +142,14 @@ symlinks: all ...@@ -142,6 +142,14 @@ symlinks: all
ln -sf `realpath */$(EXEODIR)/*` $(SBBSEXEC) ln -sf `realpath */$(EXEODIR)/*` $(SBBSEXEC)
endif endif
ifdef SBBSCTRL
$(EXEODIR)/textgen: $(TEXTGEN_OBJS)
$(CC) -o $@ $(TEXTGEN_OBJS) $(XPDEV_LIB) $(ENCODE_LIB) -lm
text.h: $(SBBSCTRL)/text.dat $(EXEODIR)/textgen
$(EXEODIR)/textgen
endif
.PHONY: FORCE .PHONY: FORCE
FORCE: FORCE:
......
...@@ -891,6 +891,7 @@ enum text { ...@@ -891,6 +891,7 @@ enum text {
,UserDefaultsLanguage ,UserDefaultsLanguage
,PasswordChar ,PasswordChar
,NodeConnectionSFTP ,NodeConnectionSFTP
,QWKSettingsWrapText
,TOTAL_TEXT ,TOTAL_TEXT
}; };
......
...@@ -1430,4 +1430,6 @@ const char * const text_defaults[TOTAL_TEXT]={ ...@@ -1430,4 +1430,6 @@ const char * const text_defaults[TOTAL_TEXT]={
"\x73\x0d\x0a" // 872 UserDefaultsLanguage "\x73\x0d\x0a" // 872 UserDefaultsLanguage
,"\x2a" // 873 PasswordChar ,"\x2a" // 873 PasswordChar
,"\x20\x76\x69\x61\x20\x73\x66\x74\x70" // 874 NodeConnectionSFTP ,"\x20\x76\x69\x61\x20\x73\x66\x74\x70" // 874 NodeConnectionSFTP
,"\x01\x6e\x01\x62\x5b\x01\x68\x01\x77\x57\x01\x6e\x01\x62\x5d\x20\x01\x68\x57\x6f\x72\x64\x2d\x77\x72\x61\x70\x20\x4d\x65\x73\x73"
"\x61\x67\x65\x20\x54\x65\x78\x74\x20\x20\x20\x20\x20\x20\x20\x01\x6e\x01\x62\x3a\x20\x01\x63\x25\x73\x0d\x0a" // 875 QWKSettingsWrapText
}; };
...@@ -875,4 +875,5 @@ const char* const text_id[]={ ...@@ -875,4 +875,5 @@ const char* const text_id[]={
,"UserDefaultsLanguage" ,"UserDefaultsLanguage"
,"PasswordChar" ,"PasswordChar"
,"NodeConnectionSFTP" ,"NodeConnectionSFTP"
,"QWKSettingsWrapText"
}; };
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment