Commit d2892791 authored by rswindell's avatar rswindell
Browse files

Bug-fix/enhancement: Allow QWKnet netmail to be sent using the JavaScript

MsgBase.save_msg() method. The bug was that it was forcing the idx.to value to
0 which would only work (in theory) for mail going to a QWKnet hub.
Now, save_msg() will check the 'to_net_addr' property of the header object
(or recipient objects) and actually verify that it/they are routeable QWKnet
address(es) and throw an exception if not.
If the first hop is a QWKnet node, sets the to_ext (and thus, idx.to value) to
the account number of the node. This also looks up full-routes via the
route.dat and replaces the to_net_addr value with the full route if necessary.
I guess nobody (including me) tried sending QWKnet netmail via JS before.
parent 3b397c05
......@@ -619,7 +619,7 @@ void sbbs_t::qwktonetmail(FILE *rep, char *block, char *into, uchar fromhub)
p++;
addr=p;
msg.idx.to=qwk_route(addr,fulladdr);
msg.idx.to=qwk_route(&cfg,addr,fulladdr, sizeof(fulladdr)-1);
if(!fulladdr[0]) { /* Invalid address, so BOUNCE it */
/**
errormsg(WHERE,ERR_CHK,addr,0);
......
......@@ -141,7 +141,10 @@ static BOOL parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, s
ushort agent;
int32 i32;
jsval val;
scfg_t* scfg;
scfg = JS_GetRuntimePrivate(JS_GetRuntime(cx));
if(JS_GetProperty(cx, hdr, "to", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx);
......@@ -220,8 +223,32 @@ static BOOL parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, s
free(cp);
if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
if(p->smb.status.attr&SMB_EMAIL)
msg->idx.to=0;
if(p->smb.status.attr&SMB_EMAIL) {
if(nettype==NET_QWK && msg->idx.to==0) {
char fulladdr[128];
msg->idx.to = qwk_route(scfg, msg->to_net.addr, fulladdr, sizeof(fulladdr)-1);
if(fulladdr[0]==0) {
JS_ReportError(cx, "Unrouteable QWKnet \"to_net_addr\" (%s) in recipient object"
,msg->to_net.addr);
return(FALSE);
}
if((p->status=smb_hfield_str(msg, RECIPIENTNETADDR, fulladdr))!=SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENTADDR field to message header"
,p->status);
return(FALSE);
}
if(msg->idx.to != 0) {
char ext[32];
sprintf(ext,"%u",msg->idx.to);
if((p->status=smb_hfield_str(msg, RECIPIENTEXT, ext))!=SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENTEXT field to message header"
,p->status);
return(FALSE);
}
}
} else
msg->idx.to=0;
}
if((p->status=smb_hfield_bin(msg, RECIPIENTNETTYPE, nettype))!=SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENTNETTYPE field to message header", p->status);
return(FALSE);
......
......@@ -334,7 +334,7 @@ bool sbbs_t::qnetmail(const char *into, const char *subj, long mode)
addr++;
strupr(addr);
truncsp(addr);
touser=qwk_route(addr,fulladdr);
touser=qwk_route(&cfg,addr,fulladdr,sizeof(fulladdr)-1);
if(!fulladdr[0]) {
bputs(text[InvalidNetMailAddr]);
return(false);
......
......@@ -81,9 +81,9 @@ bool route_circ(char *via, char *id)
return(false);
}
int sbbs_t::qwk_route(char *inaddr, char *fulladdr)
extern "C" int DLLCALL qwk_route(scfg_t* cfg, const char *inaddr, char *fulladdr, size_t maxlen)
{
char node[10],str[256],*p;
char node[10],str[256],path[MAX_PATH+1],*p;
int file,i;
FILE *stream;
......@@ -92,47 +92,47 @@ int sbbs_t::qwk_route(char *inaddr, char *fulladdr)
p=strrchr(str,'/');
if(p) p++;
else p=str;
sprintf(node,"%.8s",p); /* node = destination node */
SAFECOPY(node,p); /* node = destination node */
truncsp(node);
for(i=0;i<cfg.total_qhubs;i++) /* Check if destination is our hub */
if(!stricmp(cfg.qhub[i]->id,node))
for(i=0;i<cfg->total_qhubs;i++) /* Check if destination is our hub */
if(!stricmp(cfg->qhub[i]->id,node))
break;
if(i<cfg.total_qhubs) {
strcpy(fulladdr,node);
if(i<cfg->total_qhubs) {
strncpy(fulladdr,node,maxlen);
return(0);
}
i=matchuser(&cfg,node,FALSE); /* Check if destination is a node */
i=matchuser(cfg,node,FALSE); /* Check if destination is a node */
if(i) {
getuserrec(&cfg,i,U_REST,8,str);
getuserrec(cfg,i,U_REST,8,str);
if(ahtoul(str)&FLAG('Q')) {
strcpy(fulladdr,node);
strncpy(fulladdr,node,maxlen);
return(i);
}
}
sprintf(node,"%.8s",inaddr); /* node = next hop */
SAFECOPY(node,inaddr); /* node = next hop */
p=strchr(node,'/');
if(p) *p=0;
truncsp(node);
if(strchr(inaddr,'/')) { /* Multiple hops */
for(i=0;i<cfg.total_qhubs;i++) /* Check if next hop is our hub */
if(!stricmp(cfg.qhub[i]->id,node))
for(i=0;i<cfg->total_qhubs;i++) /* Check if next hop is our hub */
if(!stricmp(cfg->qhub[i]->id,node))
break;
if(i<cfg.total_qhubs) {
strcpy(fulladdr,inaddr);
if(i<cfg->total_qhubs) {
strncpy(fulladdr,inaddr,maxlen);
return(0);
}
i=matchuser(&cfg,node,FALSE); /* Check if next hop is a node */
i=matchuser(cfg,node,FALSE); /* Check if next hop is a node */
if(i) {
getuserrec(&cfg,i,U_REST,8,str);
getuserrec(cfg,i,U_REST,8,str);
if(ahtoul(str)&FLAG('Q')) {
strcpy(fulladdr,inaddr);
strncpy(fulladdr,inaddr,maxlen);
return(i);
}
}
......@@ -141,18 +141,18 @@ int sbbs_t::qwk_route(char *inaddr, char *fulladdr)
p=strchr(node,' ');
if(p) *p=0;
sprintf(str,"%sqnet/route.dat",cfg.data_dir);
if((stream=fnopen(&file,str,O_RDONLY))==NULL)
SAFEPRINTF(path,"%sqnet/route.dat",cfg->data_dir);
if((stream=fnopen(&file,path,O_RDONLY))==NULL)
return(0);
strcat(node,":");
fulladdr[0]=0;
while(!feof(stream)) {
if(!fgets(str,256,stream))
if(!fgets(str,sizeof(str),stream))
break;
if(!strnicmp(str+9,node,strlen(node))) {
truncsp(str);
sprintf(fulladdr,"%s/%s",str+9+strlen(node),inaddr);
safe_snprintf(fulladdr,maxlen,"%s/%s",str+9+strlen(node),inaddr);
break;
}
......@@ -162,20 +162,20 @@ int sbbs_t::qwk_route(char *inaddr, char *fulladdr)
if(!fulladdr[0]) /* First hop not found in ROUTE.DAT */
return(0);
sprintf(node,"%.8s",fulladdr);
SAFECOPY(node, fulladdr);
p=strchr(node,'/');
if(p) *p=0;
truncsp(node);
for(i=0;i<cfg.total_qhubs;i++) /* Check if first hop is our hub */
if(!stricmp(cfg.qhub[i]->id,node))
for(i=0;i<cfg->total_qhubs;i++) /* Check if first hop is our hub */
if(!stricmp(cfg->qhub[i]->id,node))
break;
if(i<cfg.total_qhubs)
if(i<cfg->total_qhubs)
return(0);
i=matchuser(&cfg,node,FALSE); /* Check if first hop is a node */
i=matchuser(cfg,node,FALSE); /* Check if first hop is a node */
if(i) {
getuserrec(&cfg,i,U_REST,8,str);
getuserrec(cfg,i,U_REST,8,str);
if(ahtoul(str)&FLAG('Q'))
return(i);
}
......@@ -183,7 +183,6 @@ int sbbs_t::qwk_route(char *inaddr, char *fulladdr)
return(0);
}
/* Via is in format: NODE/NODE/... */
void sbbs_t::update_qwkroute(char *via)
{
......@@ -217,7 +216,7 @@ void sbbs_t::update_qwkroute(char *via)
sprintf(str,"%sqnet/route.dat",cfg.data_dir);
if((stream=fnopen(&file,str,O_RDONLY))!=NULL) {
while(!feof(stream)) {
if(!fgets(str,255,stream))
if(!fgets(str,sizeof(str),stream))
break;
truncsp(str);
t=dstrtounix(&cfg,str);
......
......@@ -879,7 +879,6 @@ public:
bool qwklogon;
ulong qwkmail_last;
void qwk_sec(void);
int qwk_route(char *inaddr, char *fulladdr);
uint total_qwknodes;
struct qwknode {
char id[LEN_QWKID+1];
......@@ -1108,6 +1107,9 @@ extern "C" {
DLLEXPORT char* DLLCALL cmdstr(scfg_t* cfg, user_t* user, const char* instr
,const char* fpath, const char* fspec, char* cmd);
/* qwk.cpp */
DLLEXPORT int qwk_route(scfg_t*, const char *inaddr, char *fulladdr, size_t maxlen);
#ifdef JAVASCRIPT
typedef struct {
......
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