Start on qwknet support
This commit is contained in:
parent
4b90398cbf
commit
ecb1c986f0
1
.gitignore
vendored
1
.gitignore
vendored
@ -102,3 +102,4 @@ deps/libuuid/configure
|
|||||||
deps/libuuid/Makefile.in
|
deps/libuuid/Makefile.in
|
||||||
deps/libuuid/aclocal.m4
|
deps/libuuid/aclocal.m4
|
||||||
deps/libuuid/ltmain.sh
|
deps/libuuid/ltmain.sh
|
||||||
|
utils/qwknet/qwktoss
|
||||||
|
@ -23,6 +23,10 @@ LINE 289 NEW
|
|||||||
OLDSTRING: (NONE)
|
OLDSTRING: (NONE)
|
||||||
NEWSTRING: "\e[2J\e[1;1H\e[1;32mFrom : \e[1;37m%s (@%d)\r\n"
|
NEWSTRING: "\e[2J\e[1;1H\e[1;32mFrom : \e[1;37m%s (@%d)\r\n"
|
||||||
|
|
||||||
|
LINE 290 NEW
|
||||||
|
OLDSTRING: (NONE)
|
||||||
|
NEWSTRING: "\e[2J\e[1;1H\e[1;32mFrom : \e[1;37m%s (%s)\r\n"
|
||||||
|
|
||||||
Changes from v0.9-alpha -> v0.10-alpha
|
Changes from v0.9-alpha -> v0.10-alpha
|
||||||
--------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
1
dist/magicka.strings
vendored
1
dist/magicka.strings
vendored
@ -287,3 +287,4 @@ Read Now ? (Y / N):
|
|||||||
\e[1;30m[\e[1;34;44m%5d\e[1;30;40m]\e[1;31m!\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n
|
\e[1;30m[\e[1;34;44m%5d\e[1;30;40m]\e[1;31m!\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n
|
||||||
\e[1;30m[\e[1;34m%5d\e[1;30m]\e[1;31m!\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n
|
\e[1;30m[\e[1;34m%5d\e[1;30m]\e[1;31m!\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n
|
||||||
\e[2J\e[1;1H\e[1;32mFrom : \e[1;37m%s (@%d)\r\n
|
\e[2J\e[1;1H\e[1;32mFrom : \e[1;37m%s (@%d)\r\n
|
||||||
|
\e[2J\e[1;1H\e[1;32mFrom : \e[1;37m%s (%s)\r\n
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define NETWORK_FIDO 1
|
#define NETWORK_FIDO 1
|
||||||
#define NETWORK_WWIV 2
|
#define NETWORK_WWIV 2
|
||||||
#define NETWORK_MAGI 3
|
#define NETWORK_MAGI 3
|
||||||
|
#define NETWORK_QWK 4
|
||||||
|
|
||||||
#define TYPE_LOCAL_AREA 0
|
#define TYPE_LOCAL_AREA 0
|
||||||
#define TYPE_NETMAIL_AREA 1
|
#define TYPE_NETMAIL_AREA 1
|
||||||
@ -82,7 +83,6 @@ struct mail_conference {
|
|||||||
int mail_area_count;
|
int mail_area_count;
|
||||||
struct mail_area **mail_areas;
|
struct mail_area **mail_areas;
|
||||||
struct fido_addr *fidoaddr;
|
struct fido_addr *fidoaddr;
|
||||||
int wwivnode;
|
|
||||||
int maginode;
|
int maginode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -695,6 +695,12 @@ int bwave_add_message(int confr, int area, unsigned int dwritten, char *to, char
|
|||||||
jsf.Buffer = (char *)buffer;
|
jsf.Buffer = (char *)buffer;
|
||||||
JAM_PutSubfield(jsp, &jsf);
|
JAM_PutSubfield(jsp, &jsf);
|
||||||
jmh.MsgIdCRC = JAM_Crc32(buffer, strlen(buffer));
|
jmh.MsgIdCRC = JAM_Crc32(buffer, strlen(buffer));
|
||||||
|
} else if (conf.mail_conferences[confr]->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);
|
||||||
}
|
}
|
||||||
} else if (conf.mail_conferences[confr]->mail_areas[area]->type == TYPE_NETMAIL_AREA && conf.mail_conferences[confr]->nettype == NETWORK_FIDO) {
|
} else if (conf.mail_conferences[confr]->mail_areas[area]->type == TYPE_NETMAIL_AREA && conf.mail_conferences[confr]->nettype == NETWORK_FIDO) {
|
||||||
jmh.Attribute |= JAM_MSG_TYPENET;
|
jmh.Attribute |= JAM_MSG_TYPENET;
|
||||||
@ -1081,6 +1087,8 @@ void bwave_upload_reply() {
|
|||||||
}
|
}
|
||||||
} else if (conf.mail_conferences[confr]->nettype == NETWORK_MAGI) {
|
} else if (conf.mail_conferences[confr]->nettype == NETWORK_MAGI) {
|
||||||
snprintf(originlinebuffer, 256, "\r--- %s\r * Origin: %s (@%d)\r", upl_hdr.reader_tear, tagline, conf.mail_conferences[confr]->maginode);
|
snprintf(originlinebuffer, 256, "\r--- %s\r * Origin: %s (@%d)\r", upl_hdr.reader_tear, tagline, conf.mail_conferences[confr]->maginode);
|
||||||
|
} else if (conf.mail_conferences[confr]->nettype == NETWORK_QWK) {
|
||||||
|
snprintf(originlinebuffer, 256, "\r--- $s\r * Origin: %s (%s)\r", upl_hdr.reader_tear, tagline, conf.bwave_name);
|
||||||
} else {
|
} else {
|
||||||
snprintf(originlinebuffer, 256, "\r");
|
snprintf(originlinebuffer, 256, "\r");
|
||||||
}
|
}
|
||||||
|
@ -555,6 +555,8 @@ char *external_editor(struct user_record *user, char *to, char *from, char *quot
|
|||||||
}
|
}
|
||||||
} else if (conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_MAGI && !email) {
|
} else if (conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_MAGI && !email) {
|
||||||
snprintf(buffer, 256, "\r--- MagickaBBS v%d.%d%s (%s/%s)\r * Origin: %s (@%d)\r", VERSION_MAJOR, VERSION_MINOR, VERSION_STR, name.sysname, name.machine, tagline, conf.mail_conferences[user->cur_mail_conf]->maginode);
|
snprintf(buffer, 256, "\r--- MagickaBBS v%d.%d%s (%s/%s)\r * Origin: %s (@%d)\r", VERSION_MAJOR, VERSION_MINOR, VERSION_STR, name.sysname, name.machine, tagline, conf.mail_conferences[user->cur_mail_conf]->maginode);
|
||||||
|
} else if (conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_QWK && !email) {
|
||||||
|
snprintf(buffer, 256, "\r--- MagickaBBS v%d.%d%s (%s/%s)\r * Origin: %s (%s)\r", VERSION_MAJOR, VERSION_MINOR, VERSION_STR, name.sysname, name.machine, tagline, conf.bwave_name);
|
||||||
} else {
|
} else {
|
||||||
snprintf(buffer, 256, "\r");
|
snprintf(buffer, 256, "\r");
|
||||||
}
|
}
|
||||||
@ -691,6 +693,8 @@ char *editor(struct user_record *user, char *quote, int quotelen, char *from, in
|
|||||||
}
|
}
|
||||||
} else if (conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_MAGI && !email) {
|
} else if (conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_MAGI && !email) {
|
||||||
snprintf(buffer, 256, "\r--- MagickaBBS v%d.%d%s (%s/%s)\r * Origin: %s (@%d)\r", VERSION_MAJOR, VERSION_MINOR, VERSION_STR, name.sysname, name.machine, tagline, conf.mail_conferences[user->cur_mail_conf]->maginode);
|
snprintf(buffer, 256, "\r--- MagickaBBS v%d.%d%s (%s/%s)\r * Origin: %s (@%d)\r", VERSION_MAJOR, VERSION_MINOR, VERSION_STR, name.sysname, name.machine, tagline, conf.mail_conferences[user->cur_mail_conf]->maginode);
|
||||||
|
} else if (conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_QWK && !email) {
|
||||||
|
snprintf(buffer, 256, "\r--- MagickaBBS v%d.%d%s (%s/%s)\r * Origin: %s (%s)\r", VERSION_MAJOR, VERSION_MINOR, VERSION_STR, name.sysname, name.machine, tagline, conf.bwave_name);
|
||||||
} else {
|
} else {
|
||||||
snprintf(buffer, 256, "\r");
|
snprintf(buffer, 256, "\r");
|
||||||
}
|
}
|
||||||
@ -1581,6 +1585,8 @@ int read_message(struct user_record *user, struct msg_headers *msghs, int mailno
|
|||||||
free(from_addr);
|
free(from_addr);
|
||||||
} else if (msghs->msgs[mailno]->oaddress != NULL && conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_MAGI) {
|
} else if (msghs->msgs[mailno]->oaddress != NULL && conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_MAGI) {
|
||||||
s_printf(get_string(288), msghs->msgs[mailno]->from, atoi(msghs->msgs[mailno]->oaddress));
|
s_printf(get_string(288), msghs->msgs[mailno]->from, atoi(msghs->msgs[mailno]->oaddress));
|
||||||
|
} else if (msghs->msgs[mailno]->oaddress != NULL && conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_QWK) {
|
||||||
|
s_printf(get_string(289), msghs->msgs[mailno]->from, msghs->msgs[mailno]->oaddress);
|
||||||
} else {
|
} else {
|
||||||
s_printf(get_string(106), msghs->msgs[mailno]->from);
|
s_printf(get_string(106), msghs->msgs[mailno]->from);
|
||||||
}
|
}
|
||||||
@ -1872,6 +1878,12 @@ int read_message(struct user_record *user, struct msg_headers *msghs, int mailno
|
|||||||
JAM_PutSubfield(jsp, &jsf);
|
JAM_PutSubfield(jsp, &jsf);
|
||||||
jmh.ReplyCRC = JAM_Crc32(buffer, strlen(buffer));
|
jmh.ReplyCRC = JAM_Crc32(buffer, strlen(buffer));
|
||||||
}
|
}
|
||||||
|
} else if (conf.mail_conferences[user->cur_mail_conf]->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);
|
||||||
}
|
}
|
||||||
} else if (conf.mail_conferences[user->cur_mail_conf]->mail_areas[user->cur_mail_area]->type == TYPE_NETMAIL_AREA) {
|
} else if (conf.mail_conferences[user->cur_mail_conf]->mail_areas[user->cur_mail_area]->type == TYPE_NETMAIL_AREA) {
|
||||||
jmh.Attribute |= JAM_MSG_TYPENET;
|
jmh.Attribute |= JAM_MSG_TYPENET;
|
||||||
@ -2327,9 +2339,14 @@ void post_message(struct user_record *user) {
|
|||||||
JAM_PutSubfield(jsp, &jsf);
|
JAM_PutSubfield(jsp, &jsf);
|
||||||
jmh.MsgIdCRC = JAM_Crc32(buffer, strlen(buffer));
|
jmh.MsgIdCRC = JAM_Crc32(buffer, strlen(buffer));
|
||||||
|
|
||||||
}
|
} else if (conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_QWK) {
|
||||||
} else
|
jsf.LoID = JAMSFLD_OADDRESS;
|
||||||
if (conf.mail_conferences[user->cur_mail_conf]->mail_areas[user->cur_mail_area]->type == TYPE_NETMAIL_AREA) {
|
jsf.HiID = 0;
|
||||||
|
jsf.DatLen = strlen(conf.bwave_name);
|
||||||
|
jsf.Buffer = (char *)conf.bwave_name;
|
||||||
|
JAM_PutSubfield(jsp, &jsf);
|
||||||
|
}
|
||||||
|
} else if (conf.mail_conferences[user->cur_mail_conf]->mail_areas[user->cur_mail_area]->type == TYPE_NETMAIL_AREA) {
|
||||||
jmh.Attribute |= JAM_MSG_TYPENET;
|
jmh.Attribute |= JAM_MSG_TYPENET;
|
||||||
jmh.Attribute |= JAM_MSG_PRIVATE;
|
jmh.Attribute |= JAM_MSG_PRIVATE;
|
||||||
if (conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_FIDO) {
|
if (conf.mail_conferences[user->cur_mail_conf]->nettype == NETWORK_FIDO) {
|
||||||
|
@ -337,6 +337,8 @@ static int mail_area_handler(void* user, const char* section, const char* name,
|
|||||||
mc->nettype = NETWORK_FIDO;
|
mc->nettype = NETWORK_FIDO;
|
||||||
} else if (strcasecmp(value, "magi") == 0) {
|
} else if (strcasecmp(value, "magi") == 0) {
|
||||||
mc->nettype = NETWORK_MAGI;
|
mc->nettype = NETWORK_MAGI;
|
||||||
|
} else if (strcasecmp(value, "qwk") == 0) {
|
||||||
|
mc->nettype = NETWORK_QWK;
|
||||||
}
|
}
|
||||||
} else if (strcasecmp(name, "fido node") == 0) {
|
} else if (strcasecmp(name, "fido node") == 0) {
|
||||||
mc->fidoaddr = parse_fido_addr(value);
|
mc->fidoaddr = parse_fido_addr(value);
|
||||||
|
21
utils/qwknet/Makefile
Normal file
21
utils/qwknet/Makefile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
CC=cc
|
||||||
|
CFLAGS=-I/usr/local/include -ggdb
|
||||||
|
DEPS = qwktoss.c
|
||||||
|
JAMLIB = ../../deps/jamlib/jamlib.a
|
||||||
|
OBJ = qwktoss.o ../../src/inih/ini.o
|
||||||
|
|
||||||
|
all: qwktoss
|
||||||
|
|
||||||
|
%.o: %.c $(DEPS)
|
||||||
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
||||||
|
$(JAMLIB):
|
||||||
|
cd ../../deps/jamlib && make -f Makefile.linux
|
||||||
|
|
||||||
|
qwktoss: $(OBJ) $(JAMLIB)
|
||||||
|
$(CC) -o qwktoss $^ $(CFLAGS) -L/usr/local/lib
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJ) qwktoss
|
16
utils/qwknet/qwk.h
Normal file
16
utils/qwknet/qwk.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
struct QwkHeader {
|
||||||
|
unsigned char Msgstat; /* Message status */
|
||||||
|
unsigned char Msgnum[7]; /* Message number */
|
||||||
|
unsigned char Msgdate[8]; /* Message date MM-DD-YY*/
|
||||||
|
unsigned char Msgtime[5]; /* Message time HH:MM */
|
||||||
|
unsigned char MsgTo[25]; /* Message To: */
|
||||||
|
unsigned char MsgFrom[25]; /* Message From: */
|
||||||
|
unsigned char MsgSubj[25]; /* Message Subject: */
|
||||||
|
unsigned char Msgpass[12]; /* Message password */
|
||||||
|
unsigned char Msgrply[8]; /* Message reply to */
|
||||||
|
unsigned char Msgrecs[6]; /* Length in records */
|
||||||
|
unsigned char Msglive; /* Message active status*/
|
||||||
|
unsigned char Msgarealo; /* Lo-byte message area */
|
||||||
|
unsigned char Msgareahi; /* Hi-byte message area */
|
||||||
|
unsigned char Msgfiller[3]; /* Filler bytes */
|
||||||
|
} __attribute__((packed));
|
6
utils/qwknet/qwk.ini
Normal file
6
utils/qwknet/qwk.ini
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[Main]
|
||||||
|
Message Path = /home/andrew/MagickaBBS/msgs/dovenet
|
||||||
|
Inbound = /home/andrew/MagickaBBS/qwk/in
|
||||||
|
Outbound = /home/andrew/MagickaBBS/qwk/out
|
||||||
|
Temp Dir = /home/andrew/MagickaBBS/qwm/Temp
|
||||||
|
Unpack Command = unzip -j -o *a -d *d
|
388
utils/qwknet/qwktoss.c
Normal file
388
utils/qwknet/qwktoss.c
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <fts.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "qwk.h"
|
||||||
|
#include "../../deps/jamlib/jam.h"
|
||||||
|
#include "../../src/inih/ini.h"
|
||||||
|
|
||||||
|
char *inbound_path;
|
||||||
|
char *message_base_path;
|
||||||
|
char *temp_dir;
|
||||||
|
char *unpack_cmd;
|
||||||
|
|
||||||
|
int recursive_delete(const char *dir) {
|
||||||
|
int ret = 0;
|
||||||
|
FTS *ftsp = NULL;
|
||||||
|
FTSENT *curr;
|
||||||
|
|
||||||
|
char *files[] = { (char *) dir, NULL };
|
||||||
|
|
||||||
|
ftsp = fts_open(files, FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV, NULL);
|
||||||
|
if (!ftsp) {
|
||||||
|
fprintf(stderr, "%s: fts_open failed: %s\n", dir, strerror(errno));
|
||||||
|
ret = -1;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((curr = fts_read(ftsp))) {
|
||||||
|
switch (curr->fts_info) {
|
||||||
|
case FTS_NS:
|
||||||
|
case FTS_DNR:
|
||||||
|
case FTS_ERR:
|
||||||
|
fprintf(stderr, "%s: fts_read error: %s\n", curr->fts_accpath, strerror(curr->fts_errno));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FTS_DC:
|
||||||
|
case FTS_DOT:
|
||||||
|
case FTS_NSOK:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FTS_D:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FTS_DP:
|
||||||
|
case FTS_F:
|
||||||
|
case FTS_SL:
|
||||||
|
case FTS_SLNONE:
|
||||||
|
case FTS_DEFAULT:
|
||||||
|
if (remove(curr->fts_accpath) < 0) {
|
||||||
|
fprintf(stderr, "%s: Failed to remove: %s", curr->fts_path, strerror(errno));
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finish:
|
||||||
|
if (ftsp) {
|
||||||
|
fts_close(ftsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_JamBase *open_jam_base(char *path) {
|
||||||
|
int ret;
|
||||||
|
s_JamBase *jb;
|
||||||
|
|
||||||
|
ret = JAM_OpenMB((char *)path, &jb);
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
if (ret == JAM_IO_ERROR) {
|
||||||
|
free(jb);
|
||||||
|
ret = JAM_CreateMB((char *)path, 1, &jb);
|
||||||
|
if (ret != 0) {
|
||||||
|
free(jb);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
free(jb);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handler(void* user, const char* section, const char* name,
|
||||||
|
const char* value)
|
||||||
|
{
|
||||||
|
if (strcasecmp(section, "main") == 0) {
|
||||||
|
if (strcasecmp(name, "message path") == 0) {
|
||||||
|
message_base_path = strdup(value);
|
||||||
|
} else if (strcasecmp(name, "inbound") == 0) {
|
||||||
|
inbound_path = strdup(value);
|
||||||
|
} else if (strcasecmp(name, "temp dir") == 0) {
|
||||||
|
temp_dir = strdup(value);
|
||||||
|
} else if (strcasecmp(name, "unpack command") == 0) {
|
||||||
|
unpack_cmd = strdup(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t trimwhitespace(char *out, size_t len, const char *str) {
|
||||||
|
if(len == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const char *end;
|
||||||
|
size_t out_size;
|
||||||
|
|
||||||
|
// Trim trailing space
|
||||||
|
end = str + strlen(str) - 1;
|
||||||
|
while(end > str && isspace((unsigned char)*end)) end--;
|
||||||
|
end++;
|
||||||
|
|
||||||
|
// Set output size to minimum of trimmed string length and buffer size minus 1
|
||||||
|
out_size = (end - str) < len-1 ? (end - str) : len-1;
|
||||||
|
|
||||||
|
// Copy trimmed string and add null terminator
|
||||||
|
memcpy(out, str, out_size);
|
||||||
|
out[out_size] = 0;
|
||||||
|
|
||||||
|
return out_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int process_msgs_dat(char *msgsdat) {
|
||||||
|
FILE *fptr;
|
||||||
|
char buffer[PATH_MAX];
|
||||||
|
struct QwkHeader qhdr;
|
||||||
|
int msgrecs;
|
||||||
|
unsigned char *msgbody;
|
||||||
|
char mbuf[129];
|
||||||
|
int i;
|
||||||
|
time_t msgdate;
|
||||||
|
struct tm thedate;
|
||||||
|
int year;
|
||||||
|
char msgto[26];
|
||||||
|
char msgfrom[26];
|
||||||
|
char msgsubj[26];
|
||||||
|
unsigned int msgconf;
|
||||||
|
s_JamBase *jb;
|
||||||
|
s_JamMsgHeader jmh;
|
||||||
|
s_JamSubPacket* jsp;
|
||||||
|
s_JamSubfield jsf;
|
||||||
|
int z;
|
||||||
|
|
||||||
|
snprintf(buffer, PATH_MAX, "%s/%s", temp_dir, msgsdat);
|
||||||
|
|
||||||
|
fptr = fopen(buffer, "rb");
|
||||||
|
|
||||||
|
if (!fptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fread(&qhdr, sizeof(struct QwkHeader), 1, fptr);
|
||||||
|
while (!feof(fptr)) {
|
||||||
|
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);
|
||||||
|
for (i=1;i<msgrecs;i++) {
|
||||||
|
fread(mbuf, 1, 128, fptr);
|
||||||
|
if (i == msgrecs - 1) {
|
||||||
|
trimwhitespace(msgbody + (i * 128), 128, mbuf);
|
||||||
|
} else {
|
||||||
|
memcpy(msgbody + (i * 128), mbuf, 128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&thedate, 0, sizeof(struct tm));
|
||||||
|
|
||||||
|
thedate.tm_mday = (qhdr.Msgdate[3] - '0') * 10 + (qhdr.Msgdate[4] - '0');
|
||||||
|
thedate.tm_mon = ((qhdr.Msgdate[0] - '0') * 10 + (qhdr.Msgdate[1] - '0')) - 1;
|
||||||
|
year = (qhdr.Msgdate[6] - '0') * 10 + (qhdr.Msgdate[7] - '0');
|
||||||
|
if (year < 80) {
|
||||||
|
year += 100;
|
||||||
|
}
|
||||||
|
thedate.tm_year = year;
|
||||||
|
|
||||||
|
thedate.tm_hour = (qhdr.Msgtime[0] -'0') * 10 + (qhdr.Msgtime[1] - '0');
|
||||||
|
thedate.tm_min = (qhdr.Msgtime[3] -'0') * 10 + (qhdr.Msgtime[4] - '0');
|
||||||
|
|
||||||
|
msgdate = mktime(&thedate);
|
||||||
|
|
||||||
|
memset(buffer, 0, PATH_MAX);
|
||||||
|
memset(msgto, 0, 26);
|
||||||
|
strncpy(buffer, qhdr.MsgTo, 25);
|
||||||
|
trimwhitespace(msgto, 25, buffer);
|
||||||
|
|
||||||
|
memset(buffer, 0, PATH_MAX);
|
||||||
|
memset(msgfrom, 0, 26);
|
||||||
|
strncpy(buffer, qhdr.MsgFrom, 25);
|
||||||
|
trimwhitespace(msgfrom, 25, buffer);
|
||||||
|
|
||||||
|
memset(buffer, 0, PATH_MAX);
|
||||||
|
memset(msgsubj, 0, 26);
|
||||||
|
strncpy(buffer, qhdr.MsgSubj, 25);
|
||||||
|
trimwhitespace(msgsubj, 25, buffer);
|
||||||
|
|
||||||
|
msgconf = ((qhdr.Msgareahi & 0xff) << 8) | qhdr.Msgarealo;
|
||||||
|
|
||||||
|
snprintf(buffer, PATH_MAX, "%s/%d", message_base_path, msgconf);
|
||||||
|
|
||||||
|
jb = open_jam_base(buffer);
|
||||||
|
if (!jb) {
|
||||||
|
fprintf(stderr, "Unable to open JAM base: %s\n", buffer);
|
||||||
|
free(msgbody);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
JAM_ClearMsgHeader( &jmh );
|
||||||
|
jmh.DateWritten = msgdate;
|
||||||
|
|
||||||
|
jsp = JAM_NewSubPacket();
|
||||||
|
|
||||||
|
jsf.LoID = JAMSFLD_SENDERNAME;
|
||||||
|
jsf.HiID = 0;
|
||||||
|
jsf.DatLen = strlen(msgfrom);
|
||||||
|
jsf.Buffer = (char *)msgfrom;
|
||||||
|
JAM_PutSubfield(jsp, &jsf);
|
||||||
|
|
||||||
|
jsf.LoID = JAMSFLD_RECVRNAME;
|
||||||
|
jsf.HiID = 0;
|
||||||
|
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;
|
||||||
|
JAM_PutSubfield(jsp, &jsf);
|
||||||
|
|
||||||
|
jmh.Attribute |= JAM_MSG_TYPEECHO;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
z = JAM_LockMB(jb, 100);
|
||||||
|
if (z == 0) {
|
||||||
|
break;
|
||||||
|
} else if (z == JAM_LOCK_FAILED) {
|
||||||
|
sleep(1);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Failed to lock msg base!\n");
|
||||||
|
JAM_CloseMB(jb);
|
||||||
|
free(jb);
|
||||||
|
free(msgbody);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (JAM_AddMessage(jb, &jmh, jsp, (char *)msgbody, strlen(msgbody))) {
|
||||||
|
fprintf(stderr, "Failed to add message\n");
|
||||||
|
JAM_UnlockMB(jb);
|
||||||
|
|
||||||
|
JAM_DelSubPacket(jsp);
|
||||||
|
JAM_CloseMB(jb);
|
||||||
|
free(jb);
|
||||||
|
free(msgbody);
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
JAM_UnlockMB(jb);
|
||||||
|
|
||||||
|
JAM_DelSubPacket(jsp);
|
||||||
|
JAM_CloseMB(jb);
|
||||||
|
free(jb);
|
||||||
|
free(msgbody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int process_qwk_file(char *qwkfile) {
|
||||||
|
// unpack file
|
||||||
|
int i;
|
||||||
|
char buffer[PATH_MAX];
|
||||||
|
int bpos = 0;
|
||||||
|
struct stat st;
|
||||||
|
int ret;
|
||||||
|
DIR *tmpb;
|
||||||
|
struct dirent *dent;
|
||||||
|
|
||||||
|
for (i=0;i<strlen(unpack_cmd);i++) {
|
||||||
|
if (unpack_cmd[i] == '*') {
|
||||||
|
i++;
|
||||||
|
if (unpack_cmd[i] == 'a') {
|
||||||
|
sprintf(&buffer[bpos], "%s/%s", inbound_path, qwkfile);
|
||||||
|
bpos = strlen(buffer);
|
||||||
|
} else if (unpack_cmd[i] == 'd') {
|
||||||
|
sprintf(&buffer[bpos], "%s", temp_dir);
|
||||||
|
bpos = strlen(buffer);
|
||||||
|
} else if (unpack_cmd[i] == '*') {
|
||||||
|
buffer[bpos++] = '*';
|
||||||
|
buffer[bpos] = '\0';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buffer[bpos++] = unpack_cmd[i];
|
||||||
|
buffer[bpos] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if tempdir exists
|
||||||
|
|
||||||
|
if (stat(temp_dir, &st) == 0) {
|
||||||
|
fprintf(stderr, "Temp Path exists! Please delete it first\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir(temp_dir, 0755);
|
||||||
|
|
||||||
|
ret = system(buffer);
|
||||||
|
if (ret == -1 || ret >> 8 == 127) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// process NDXs
|
||||||
|
tmpb = opendir(temp_dir);
|
||||||
|
if (!tmpb) {
|
||||||
|
fprintf(stderr, "Error opening temp directory\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
while ((dent = readdir(tmpb)) != NULL) {
|
||||||
|
if (strcasecmp(dent->d_name, "messages.dat") == 0) {
|
||||||
|
// process tic file
|
||||||
|
ret = process_msgs_dat(dent->d_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(tmpb);
|
||||||
|
|
||||||
|
// delete temp dir
|
||||||
|
recursive_delete(temp_dir);
|
||||||
|
snprintf(buffer, PATH_MAX, "%s/%s", inbound_path, qwkfile);
|
||||||
|
remove(buffer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
// read ini file
|
||||||
|
DIR *inb;
|
||||||
|
struct dirent *dent;
|
||||||
|
|
||||||
|
|
||||||
|
message_base_path = NULL;
|
||||||
|
inbound_path = NULL;
|
||||||
|
temp_dir = NULL;
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr, "Usage:\n ./qwktoss config.ini\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ini_parse(argv[1], handler, NULL) <0) {
|
||||||
|
fprintf(stderr, "Unable to load configuration ini (%s)!\n", argv[1]);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp_dir == NULL || message_base_path == NULL || inbound_path == NULL) {
|
||||||
|
fprintf(stderr, "Message Base Path and Inbound Path must be set\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// scan for QWK files
|
||||||
|
inb = opendir(inbound_path);
|
||||||
|
if (!inb) {
|
||||||
|
fprintf(stderr, "Error opening inbound directory\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
while ((dent = readdir(inb)) != NULL) {
|
||||||
|
if (dent->d_name[strlen(dent->d_name) - 4] == '.' &&
|
||||||
|
tolower(dent->d_name[strlen(dent->d_name) - 3]) == 'q' &&
|
||||||
|
tolower(dent->d_name[strlen(dent->d_name) - 2]) == 'w' &&
|
||||||
|
tolower(dent->d_name[strlen(dent->d_name) - 1]) == 'k'
|
||||||
|
) {
|
||||||
|
// process qwk file
|
||||||
|
fprintf(stderr, "Processing QWK file %s\n", dent->d_name);
|
||||||
|
if (process_qwk_file(dent->d_name) != -1) {
|
||||||
|
|
||||||
|
rewinddir(inb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(inb);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -490,6 +490,12 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
conf.filearea_count = 0;
|
conf.filearea_count = 0;
|
||||||
conf.case_insensitve = 0;
|
conf.case_insensitve = 0;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr, "Usage: \n ./ticproc config.ini\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ini_parse(argv[1], handler, NULL) <0) {
|
if (ini_parse(argv[1], handler, NULL) <0) {
|
||||||
fprintf(stderr, "Unable to load configuration ini (%s)!\n", argv[1]);
|
fprintf(stderr, "Unable to load configuration ini (%s)!\n", argv[1]);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
Reference in New Issue
Block a user