From 0b0078b1e7af90f51bd65806aac103bd0422b747 Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Wed, 31 Oct 2018 08:42:35 +1000 Subject: [PATCH] Basic support for syncronet's headers.dat --- src/bbs.h | 1 + src/bluewave.c | 10 +++ src/mail_menu.c | 29 +++++++++ src/main.c | 5 +- src/www_msgs.c | 28 ++++++++- utils/qwknet/qwkscan.c | 67 +++++++++++++++++++- utils/qwknet/qwktoss.c | 139 ++++++++++++++++++++++++++++++++++++++--- 7 files changed, 267 insertions(+), 12 deletions(-) diff --git a/src/bbs.h b/src/bbs.h index b0da565..fb0402f 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -151,6 +151,7 @@ struct bbs_config { gid_t gid; int codepage; int ipv6; + char *external_address; char *bbs_name; char *bwave_name; char *sysop_name; diff --git a/src/bluewave.c b/src/bluewave.c index 7e83815..ffd8e51 100644 --- a/src/bluewave.c +++ b/src/bluewave.c @@ -698,6 +698,16 @@ int bwave_add_message(int confr, int area, unsigned int dwritten, char *to, char jsf.DatLen = strlen(conf.bwave_name); jsf.Buffer = (char *)conf.bwave_name; JAM_PutSubfield(jsp, &jsf); + + if (conf.external_address != NULL) { + snprintf(buffer, sizeof buffer, "<%lx.%s@%s>", generate_msgid(), basename(ma->path), conf.external_address); + + jsf.LoID = JAMSFLD_MSGID; + jsf.HiID = 0; + jsf.DatLen = strlen(buffer); + jsf.Buffer = (char *)buffer; + JAM_PutSubfield(jsp, &jsf); + } } } else if (ma->type == TYPE_NETMAIL_AREA && mc->nettype == NETWORK_FIDO) { jmh.Attribute |= JAM_MSG_TYPENET; diff --git a/src/mail_menu.c b/src/mail_menu.c index 5294fc4..582daf6 100644 --- a/src/mail_menu.c +++ b/src/mail_menu.c @@ -1731,6 +1731,25 @@ int read_message(struct user_record *user, struct msg_headers *msghs, int mailno jsf.DatLen = strlen(conf.bwave_name); jsf.Buffer = (char *)conf.bwave_name; JAM_PutSubfield(jsp, &jsf); + + if (conf.external_address != NULL) { + snprintf(buffer, sizeof buffer, "<%lx.%s@%s>", generate_msgid(), basename(ma->path), conf.external_address); + + jsf.LoID = JAMSFLD_MSGID; + jsf.HiID = 0; + jsf.DatLen = strlen(buffer); + jsf.Buffer = (char *)buffer; + JAM_PutSubfield(jsp, &jsf); + if (msghs->msgs[mailno]->msgid != NULL) { + strlcpy(buffer, msghs->msgs[mailno]->msgid, sizeof buffer); + jsf.LoID = JAMSFLD_REPLYID; + jsf.HiID = 0; + jsf.DatLen = strlen(buffer); + jsf.Buffer = (char *)buffer; + JAM_PutSubfield(jsp, &jsf); + jmh.ReplyCRC = JAM_Crc32(buffer, strlen(buffer)); + } + } } } else if (ma->type == TYPE_NETMAIL_AREA) { jmh.Attribute |= JAM_MSG_TYPENET; @@ -2181,6 +2200,16 @@ void post_message(struct user_record *user) { jsf.DatLen = strlen(conf.bwave_name); jsf.Buffer = (char *)conf.bwave_name; JAM_PutSubfield(jsp, &jsf); + + if (conf.external_address != NULL) { + snprintf(buffer, sizeof buffer, "<%lx.%s@%s>", generate_msgid(), basename(ma->path), conf.external_address); + + jsf.LoID = JAMSFLD_MSGID; + jsf.HiID = 0; + jsf.DatLen = strlen(buffer); + jsf.Buffer = (char *)buffer; + JAM_PutSubfield(jsp, &jsf); + } } } else if (ma->type == TYPE_NETMAIL_AREA) { jmh.Attribute |= JAM_MSG_TYPENET; diff --git a/src/main.c b/src/main.c index 518a6e8..be966ca 100644 --- a/src/main.c +++ b/src/main.c @@ -308,6 +308,8 @@ static int handler(void *user, const char *section, const char *name, if (strcasecmp(section, "main") == 0) { if (strcasecmp(name, "bbs name") == 0) { conf->bbs_name = strdup(value); + } else if (strcasecmp(name, "external address") == 0) { + conf->external_address = strdup(value); } else if (strcasecmp(name, "telnet port") == 0) { conf->telnet_port = atoi(value); } else if (strcasecmp(name, "enable ssh") == 0) { @@ -1178,7 +1180,8 @@ int main(int argc, char **argv) { conf.ipv6 = 0; conf.uid = getuid(); conf.gid = getgid(); - + conf.external_address = NULL; + // Load BBS data if (ini_parse(argv[1], handler, &conf) < 0) { fprintf(stderr, "Unable to load configuration ini (%s)!\n", argv[1]); diff --git a/src/www_msgs.c b/src/www_msgs.c index 7dae5f8..11f7e63 100644 --- a/src/www_msgs.c +++ b/src/www_msgs.c @@ -1049,7 +1049,7 @@ int www_send_msg(struct user_record *user, char *to, char *subj, int conference, jsf.DatLen = strlen(replyid); jsf.Buffer = (char *)replyid; JAM_PutSubfield(jsp, &jsf); - jmh.ReplyCRC = JAM_Crc32(buffer, strlen(replyid)); + jmh.ReplyCRC = JAM_Crc32(replyid, strlen(replyid)); } } else if (mc->nettype == NETWORK_MAGI) { snprintf(buffer, sizeof buffer, "%d", mc->maginode); @@ -1075,7 +1075,31 @@ int www_send_msg(struct user_record *user, char *to, char *subj, int conference, jsf.DatLen = strlen(replyid); jsf.Buffer = (char *)replyid; JAM_PutSubfield(jsp, &jsf); - jmh.ReplyCRC = JAM_Crc32(buffer, strlen(replyid)); + jmh.ReplyCRC = JAM_Crc32(replyid, strlen(replyid)); + } + } else if (mc->nettype == NETWORK_QWK) { + jsf.LoID = JAMSFLD_OADDRESS; + jsf.HiID = 0; + jsf.DatLen = strlen(conf.bwave_name); + jsf.Buffer = (char *)conf.bwave_name; + JAM_PutSubfield(jsp, &jsf); + + if (conf.external_address != NULL) { + snprintf(buffer, sizeof buffer, "<%lx.%s@%s>", generate_msgid(), basename(ma->path), conf.external_address); + + jsf.LoID = JAMSFLD_MSGID; + jsf.HiID = 0; + jsf.DatLen = strlen(buffer); + jsf.Buffer = (char *)buffer; + JAM_PutSubfield(jsp, &jsf); + if (strcasecmp(replyid, "NULL") != 0) { + jsf.LoID = JAMSFLD_REPLYID; + jsf.HiID = 0; + jsf.DatLen = strlen(replyid); + jsf.Buffer = (char *)replyid; + JAM_PutSubfield(jsp, &jsf); + jmh.ReplyCRC = JAM_Crc32(replyid, strlen(replyid)); + } } } } diff --git a/utils/qwknet/qwkscan.c b/utils/qwknet/qwkscan.c index 1405243..1c063c5 100644 --- a/utils/qwknet/qwkscan.c +++ b/utils/qwknet/qwkscan.c @@ -145,12 +145,22 @@ int export_messages(int baseno, char *basefilename, int qwkidx) { int len; int lenbytes; char buffer[PATH_MAX]; + struct QwkHeader qh; struct tm msgtm; FILE *fptr; + FILE *hdrptr; char text[128]; char *msgbuf; char *msgptr; + + long offset; + + char *msgsubj = NULL; + char *msgto = NULL; + char *msgfrom = NULL; + char *msgid = NULL; + char *msgreplyid = NULL; snprintf(buffer, PATH_MAX, "%s/%s", message_base_path, basefilename); @@ -178,6 +188,10 @@ int export_messages(int baseno, char *basefilename, int qwkidx) { // export message for (z=0;zNumFields;z++) { if (jsp->Fields[z]->LoID == JAMSFLD_SUBJECT) { + msgsubj = (char *)malloc(jsp->Fields[z]->DatLen + 1); + memset(msgsubj, 0, jsp->Fields[z]->DatLen + 1); + memcpy(msgsubj, jsp->Fields[z]->Buffer, jsp->Fields[z]->DatLen); + if (jsp->Fields[z]->DatLen > 24) { len = 24; } else { @@ -187,6 +201,9 @@ int export_messages(int baseno, char *basefilename, int qwkidx) { memcpy(qh.MsgSubj, jsp->Fields[z]->Buffer, len); } if (jsp->Fields[z]->LoID == JAMSFLD_SENDERNAME) { + msgfrom = (char *)malloc(jsp->Fields[z]->DatLen + 1); + memset(msgfrom, 0, jsp->Fields[z]->DatLen + 1); + memcpy(msgfrom, jsp->Fields[z]->Buffer, jsp->Fields[z]->DatLen); if (jsp->Fields[z]->DatLen > 24) { len = 24; } else { @@ -196,6 +213,9 @@ int export_messages(int baseno, char *basefilename, int qwkidx) { memcpy(qh.MsgFrom, jsp->Fields[z]->Buffer, len); } if (jsp->Fields[z]->LoID == JAMSFLD_RECVRNAME) { + msgto = (char *)malloc(jsp->Fields[z]->DatLen + 1); + memset(msgto, 0, jsp->Fields[z]->DatLen + 1); + memcpy(msgto, jsp->Fields[z]->Buffer, jsp->Fields[z]->DatLen); if (jsp->Fields[z]->DatLen > 24) { len = 24; } else { @@ -204,6 +224,16 @@ int export_messages(int baseno, char *basefilename, int qwkidx) { memset(qh.MsgTo, ' ', 25); memcpy(qh.MsgTo, jsp->Fields[z]->Buffer, len); } + if (jsp->Fields[z]->LoID == JAMSFLD_MSGID) { + msgid = (char *)malloc(jsp->Fields[z]->DatLen + 1); + memset(msgid, 0, jsp->Fields[z]->DatLen + 1); + memcpy(msgid, jsp->Fields[z]->Buffer, jsp->Fields[z]->DatLen); + } + if (jsp->Fields[z]->LoID == JAMSFLD_REPLYID) { + msgreplyid = (char *)malloc(jsp->Fields[z]->DatLen + 1); + memset(msgreplyid, 0, jsp->Fields[z]->DatLen + 1); + memcpy(msgreplyid, jsp->Fields[z]->Buffer, jsp->Fields[z]->DatLen); + } } qh.Msgstat = ' '; snprintf(buffer, 7, "%d", baseno); @@ -276,6 +306,41 @@ int export_messages(int baseno, char *basefilename, int qwkidx) { fseek(fptr, 0, SEEK_END); } + offset = ftell(fptr); + + snprintf(buffer, PATH_MAX, "%s/HEADERS.DAT", temp_dir); + hdrptr = fopen(buffer, "a"); + + fprintf(hdrptr, "[%x]\n", offset); + if (msgid != NULL) { + fprintf(hdrptr, "Message-ID: %s\n", msgid); + free(msgid); + msgid = NULL; + } + if (msgreplyid != NULL) { + fprintf(hdrptr, "In-Reply-To: %s\n", msgreplyid); + free(msgreplyid); + msgreplyid = NULL; + } + if (msgsubj != NULL) { + fprintf(hdrptr, "Subject: %s\n", msgsubj); + free(msgsubj); + msgsubj = NULL; + } + if (msgto != NULL) { + fprintf(hdrptr, "To: %s\n", msgto); + free(msgto); + msgto = NULL; + } + if (msgfrom != NULL) { + fprintf(hdrptr, "Sender: %s\n", msgfrom); + free(msgfrom); + msgfrom = NULL; + } + + fprintf(hdrptr, "\n"); + fclose(hdrptr); + fwrite(&qh, 128, 1, fptr); fwrite(msgbuf, lenbytes - 128, 1, fptr); fclose(fptr); @@ -362,7 +427,7 @@ int main(int argc, char **argv) { strncpy(b, archive, blen); alen = strlen(archive); } else if (*p == 'f') { - snprintf(b, blen, "%s/%s.MSG", temp_dir, hostid); + snprintf(b, blen, "%s/%s.MSG %s/HEADERS.DAT", temp_dir, hostid, temp_dir); alen = strlen(b); } else if (*p == '*') { *b++ = '*'; diff --git a/utils/qwknet/qwktoss.c b/utils/qwknet/qwktoss.c index 3206b9a..e9eb4de 100644 --- a/utils/qwknet/qwktoss.c +++ b/utils/qwknet/qwktoss.c @@ -24,6 +24,20 @@ struct msg_bases { char *path; }; +struct header_t { + char *key; + char *value; +}; + +struct msg_headers_t { + long offset; + struct header_t **headers; + int header_count; +}; + +struct msg_headers_t **msg_headers; +int msg_count = 0; + struct msg_bases **msgbases; int msgbasecount = 0; @@ -100,6 +114,59 @@ s_JamBase *open_jam_base(char *path) { return jb; } +static char *get_key_value(struct msg_headers_t *header, char *key) { + if (header == NULL) return NULL; + for (int i=0;iheader_count;i++) { + if (strcmp(key, header->headers[i]->key) == 0) { + fprintf(stderr, "%s\n", header->headers[i]->value); + return header->headers[i]->value; + } + } + return NULL; +} + +static struct msg_headers_t *get_header(long offset) { + for (int i=0;ioffset == offset) { + return msg_headers[i]; + } + } + + return NULL; +} + +static int header_handler(void* user, const char* section, const char* name, + const char* value) +{ + for (int i=0;ioffset == strtol(section, NULL, 16)) { + msg_headers[i]->headers = (struct header_t **)realloc(msg_headers[i]->headers, sizeof(struct header_t *) * (msg_headers[i]->header_count + 1)); + msg_headers[i]->headers[msg_headers[i]->header_count] = (struct header_t *)malloc(sizeof(struct header_t)); + msg_headers[i]->headers[msg_headers[i]->header_count]->key = strdup(name); + msg_headers[i]->headers[msg_headers[i]->header_count]->value = strdup(value); + msg_headers[i]->header_count++; + return 1; + } + } + if (msg_count == 0) { + msg_headers = (struct msg_headers_t **)malloc(sizeof(struct msg_headers_t *)); + } else { + msg_headers = (struct msg_headers_t **)realloc(msg_headers, sizeof(struct msg_headers_t *) * (msg_count + 1)); + } + + msg_headers[msg_count] = (struct msg_headers_t *)malloc(sizeof(struct msg_headers_t)); + msg_headers[msg_count]->offset = strtol(section, NULL, 16); + msg_headers[msg_count]->header_count = 1; + msg_headers[msg_count]->headers = (struct header_t **)malloc(sizeof(struct header_t *)); + msg_headers[msg_count]->headers[0] = (struct header_t *)malloc(sizeof(struct header_t)); + msg_headers[msg_count]->headers[0]->key = strdup(name); + msg_headers[msg_count]->headers[0]->value = strdup(value); + + msg_count++; + + return 1; +} + static int handler(void* user, const char* section, const char* name, const char* value) { @@ -155,7 +222,9 @@ size_t trimwhitespace(char *out, size_t len, const char *str) { int process_msgs_dat(char *msgsdat) { FILE *fptr; FILE *cfgfptr; + char buffer[PATH_MAX]; + char headerfile[PATH_MAX]; struct QwkHeader qhdr; int msgrecs; char *msgbody; @@ -174,7 +243,16 @@ int process_msgs_dat(char *msgsdat) { s_JamSubfield jsf; int z; int basefound = 0; - + long offset; + char *ptr; + + struct msg_headers_t *header = NULL; + + + snprintf(headerfile, PATH_MAX, "%s/HEADERS.DAT", temp_dir); + + ini_parse(headerfile, header_handler, NULL); + snprintf(buffer, PATH_MAX, "%s/%s", temp_dir, msgsdat); fptr = fopen(buffer, "rb"); @@ -183,11 +261,15 @@ int process_msgs_dat(char *msgsdat) { return -1; } + fread(&qhdr, sizeof(struct QwkHeader), 1, fptr); while (!feof(fptr)) { + offset = ftell(fptr); + header = get_header(offset); if (fread(&qhdr, sizeof(struct QwkHeader), 1, fptr) != 1) { break; } + msgrecs = atoi(qhdr.Msgrecs); msgbody = (char *)malloc((msgrecs * 128) + 1); memset(msgbody, 0, (msgrecs * 128) + 1); @@ -278,6 +360,7 @@ int process_msgs_dat(char *msgsdat) { if (!jb) { fprintf(stderr, "Unable to open JAM base: %s\n", buffer); free(msgbody); + fclose(fptr); return -1; } JAM_ClearMsgHeader( &jmh ); @@ -287,22 +370,60 @@ int process_msgs_dat(char *msgsdat) { jsf.LoID = JAMSFLD_SENDERNAME; jsf.HiID = 0; - jsf.DatLen = strlen(msgfrom); - jsf.Buffer = (char *)msgfrom; + + ptr = get_key_value(header, "Sender"); + if (ptr != NULL) { + jsf.DatLen = strlen(ptr); + jsf.Buffer = ptr; + } else { + jsf.DatLen = strlen(msgfrom); + jsf.Buffer = (char *)msgfrom; + } JAM_PutSubfield(jsp, &jsf); - jsf.LoID = JAMSFLD_RECVRNAME; + jsf.LoID = JAMSFLD_RECVRNAME; jsf.HiID = 0; - jsf.DatLen = strlen(msgto); - jsf.Buffer = (char *)msgto; + + ptr = get_key_value(header, "To"); + if (ptr != NULL) { + jsf.DatLen = strlen(ptr); + jsf.Buffer = (char *)ptr; + } else { + jsf.DatLen = strlen(msgto); + jsf.Buffer = (char *)msgto; + } JAM_PutSubfield(jsp, &jsf); jsf.LoID = JAMSFLD_SUBJECT; jsf.HiID = 0; - jsf.DatLen = strlen(msgsubj); - jsf.Buffer = (char *)msgsubj; + ptr = get_key_value(header, "Subject"); + if (ptr != NULL) { + jsf.DatLen = strlen(ptr); + jsf.Buffer = (char *)ptr; + } else { + jsf.DatLen = strlen(msgsubj); + jsf.Buffer = (char *)msgsubj; + } JAM_PutSubfield(jsp, &jsf); + ptr = get_key_value(header, "Message-ID"); + if (ptr != NULL) { + jsf.LoID = JAMSFLD_MSGID; + jsf.HiID = 0; + jsf.DatLen = strlen(ptr); + jsf.Buffer = (char *)ptr; + JAM_PutSubfield(jsp, &jsf); + } + + ptr = get_key_value(header, "In-Reply-To"); + if (ptr != NULL) { + jsf.LoID = JAMSFLD_REPLYID; + jsf.HiID = 0; + jsf.DatLen = strlen(ptr); + jsf.Buffer = (char *)ptr; + JAM_PutSubfield(jsp, &jsf); + } + jmh.Attribute |= JAM_MSG_TYPEECHO; while (1) { @@ -313,6 +434,7 @@ int process_msgs_dat(char *msgsdat) { sleep(1); } else { fprintf(stderr, "Failed to lock msg base!\n"); + fclose(fptr); JAM_CloseMB(jb); free(jb); free(msgbody); @@ -327,6 +449,7 @@ int process_msgs_dat(char *msgsdat) { JAM_CloseMB(jb); free(jb); free(msgbody); + fclose(fptr); return -1; } else { JAM_UnlockMB(jb);