From db4822553927af7e679108aeb7c494beff5a1b2d Mon Sep 17 00:00:00 2001 From: Andrew Pamment Date: Sat, 20 Aug 2016 13:52:02 +1000 Subject: [PATCH] Conference support to WWW --- Makefile.freebsd.WWW | 2 +- Makefile.linux.WWW | 2 +- bbs.h | 28 ++ mail_menu.c | 36 +- www.c | 176 +++++++++- www/header.tpl | 1 + www/static/style.css | 76 ++++ www_email.c | 10 +- www_msgs.c | 805 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 1103 insertions(+), 33 deletions(-) create mode 100644 www_msgs.c diff --git a/Makefile.freebsd.WWW b/Makefile.freebsd.WWW index f6675a0..7bce1d2 100644 --- a/Makefile.freebsd.WWW +++ b/Makefile.freebsd.WWW @@ -6,7 +6,7 @@ ZMODEM = Xmodem/libzmodem.a LUA = lua/liblua.a MICROHTTPD=-lmicrohttpd -lb64 -OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list.o chat_system.o email.o files.o settings.o lua_glue.o strings.o www.o www_email.o +OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list.o chat_system.o email.o files.o settings.o lua_glue.o strings.o www.o www_email.o www_msgs.o %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) diff --git a/Makefile.linux.WWW b/Makefile.linux.WWW index b06fc84..a5668f3 100644 --- a/Makefile.linux.WWW +++ b/Makefile.linux.WWW @@ -6,7 +6,7 @@ ZMODEM = Xmodem/libzmodem.a LUA = lua/liblua.a MICROHTTPD=-lmicrohttpd -lb64 -OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list.o chat_system.o email.o files.o settings.o lua_glue.o strings.o www.o www_email.o +OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list.o chat_system.o email.o files.o settings.o lua_glue.o strings.o www.o www_email.o www_msgs.o %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) diff --git a/bbs.h b/bbs.h index 7850afc..0e6951c 100644 --- a/bbs.h +++ b/bbs.h @@ -7,6 +7,7 @@ #endif #include "lua/lua.h" #include "lua/lauxlib.h" +#include "jamlib/jam.h" #define VERSION_MAJOR 0 #define VERSION_MINOR 3 @@ -147,6 +148,23 @@ struct user_record { int timeson; }; +struct jam_msg { + int msg_no; + s_JamMsgHeader *msg_h; + char *from; + char *to; + char *subject; + char *oaddress; + char *daddress; + char *msgid; + char *replyid; +}; + +struct msg_headers { + struct jam_msg **msgs; + int msg_count; +}; + extern void automessage_write(struct user_record *user); extern void automessage_display(); extern void dolog(char *fmt, ...); @@ -176,10 +194,15 @@ extern void list_users(struct user_record *user); extern void main_menu(struct user_record *user); +extern s_JamBase *open_jam_base(char *path); +extern void free_message_headers(struct msg_headers *msghs); +extern struct msg_headers *read_message_headers(int msgconf, int msgarea, struct user_record *user); extern void mail_scan(struct user_record *user); extern int mail_menu(struct user_record *user); extern char *editor(struct user_record *user, char *quote, char *from, int email); extern char *external_editor(struct user_record *user, char *to, char *from, char *quote, char *qfrom, char *subject, int email); +extern int msg_is_to(struct user_record *user, char *addressed_to, char *address, int type, int rn, int msgconf); +extern int msg_is_from(struct user_record *user, char *addressed_from, char *address, int type, int rn, int msgconf); extern int door_menu(struct user_record *user); extern void rundoor(struct user_record *user, char *cmd, int stdio); @@ -211,6 +234,11 @@ extern char *www_email_display(struct user_record *user, int email); extern int www_send_email(struct user_record *user, char *recipient, char *subject, char *body); extern char *www_new_email(); extern int www_email_delete(struct user_record *user, int id); +extern char *www_msgs_arealist(struct user_record *user); +extern char *www_msgs_messagelist(struct user_record *user, int conference, int area, int skip); +extern char *www_msgs_messageview(struct user_record *user, int conference, int area, int msg); +extern int www_send_msg(struct user_record *user, char *to, char *subj, int conference, int area, char *replyid, char *body); +extern char *www_new_msg(struct user_record *user, int conference, int area); #endif #endif diff --git a/mail_menu.c b/mail_menu.c index 5baae19..da2d554 100644 --- a/mail_menu.c +++ b/mail_menu.c @@ -16,22 +16,6 @@ extern struct bbs_config conf; extern struct user_record *gUser; extern int mynode; -struct jam_msg { - int msg_no; - s_JamMsgHeader *msg_h; - char *from; - char *to; - char *subject; - char *oaddress; - char *daddress; - char *msgid; - char *replyid; -}; - -struct msg_headers { - struct jam_msg **msgs; - int msg_count; -}; s_JamBase *open_jam_base(char *path) { int ret; @@ -89,16 +73,16 @@ void free_message_headers(struct msg_headers *msghs) { free(msghs); } -int msg_is_to(char *addressed_to, char *address, int type, int rn, int msgconf) { +int msg_is_to(struct user_record *user, char *addressed_to, char *address, int type, int rn, int msgconf) { char *myname; char *wwiv_addressee; struct fido_addr *dest; int j; if (rn) { - myname = (char *)malloc(strlen(gUser->firstname) + strlen(gUser->lastname) + 2); - sprintf(myname, "%s %s", gUser->firstname, gUser->lastname); + myname = (char *)malloc(strlen(user->firstname) + strlen(user->lastname) + 2); + sprintf(myname, "%s %s", user->firstname, user->lastname); } else { - myname = strdup(gUser->loginname); + myname = strdup(user->loginname); } if (type == NETWORK_WWIV) { wwiv_addressee = strdup(addressed_to); @@ -145,15 +129,15 @@ int msg_is_to(char *addressed_to, char *address, int type, int rn, int msgconf) } } -int msg_is_from(char *addressed_from, char *address, int type, int rn, int msgconf) { +int msg_is_from(struct user_record *user, char *addressed_from, char *address, int type, int rn, int msgconf) { char *myname; struct fido_addr *orig; int j; if (rn) { - myname = (char *)malloc(strlen(gUser->firstname) + strlen(gUser->lastname) + 2); - sprintf(myname, "%s %s", gUser->firstname, gUser->lastname); + myname = (char *)malloc(strlen(user->firstname) + strlen(user->lastname) + 2); + sprintf(myname, "%s %s", user->firstname, user->lastname); } else { - myname = strdup(gUser->loginname); + myname = strdup(user->loginname); } if (type == NETWORK_WWIV) { free(myname); @@ -277,8 +261,8 @@ struct msg_headers *read_message_headers(int msgconf, int msgarea, struct user_r JAM_DelSubPacket(jsp); if (jmh.Attribute & MSG_PRIVATE) { - if (!msg_is_to(jamm->to, jamm->daddress, conf.mail_conferences[msgconf]->nettype, conf.mail_conferences[msgconf]->realnames, msgconf) && - !msg_is_from(jamm->from, jamm->oaddress, conf.mail_conferences[msgconf]->nettype, conf.mail_conferences[msgconf]->realnames, msgconf)) { + if (!msg_is_to(gUser, jamm->to, jamm->daddress, conf.mail_conferences[msgconf]->nettype, conf.mail_conferences[msgconf]->realnames, msgconf) && + !msg_is_from(gUser, jamm->from, jamm->oaddress, conf.mail_conferences[msgconf]->nettype, conf.mail_conferences[msgconf]->realnames, msgconf)) { if (jamm->subject != NULL) { free(jamm->subject); diff --git a/www.c b/www.c index 8787df2..41a493c 100644 --- a/www.c +++ b/www.c @@ -98,7 +98,11 @@ static int iterate_post (void *coninfo_cls, enum MHD_ValueKind kind, const char return MHD_NO; } } - + if (strcmp(con_info->url, "/msgs/") == 0 || strcmp(con_info->url, "/msgs") == 0) { + if (con_info->count == 6) { + return MHD_NO; + } + } return MHD_YES; } else { return MHD_NO; @@ -369,7 +373,12 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url const char *url_ = url; char *subj, *to, *body; struct connection_info_s *con_inf; - + int conference, area, msg; + char *url_copy; + char *aptr; + const char *val; + int skip; + char *replyid; if (strcmp(method, "GET") == 0) { if (*ptr == NULL) { @@ -585,7 +594,110 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url } whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1); + sprintf(whole_page, "%s%s%s", header, page, footer); + } else if (strcasecmp(url, "/msgs/") == 0 || strcasecmp(url, "/msgs") == 0) { + con_inf->user = www_auth_ok(connection, url_); + + if (con_inf->user == NULL) { + www_401(header, footer, connection); + free(header); + free(footer); + return MHD_YES; + } + page = www_msgs_arealist(con_inf->user); + if (page == NULL) { + free(header); + free(footer); + return MHD_NO; + } + whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1); + + sprintf(whole_page, "%s%s%s", header, page, footer); + } else if (strncasecmp(url, "/msgs/new/", 10) == 0) { + con_inf->user = www_auth_ok(connection, url_); + + if (con_inf->user == NULL) { + www_401(header, footer, connection); + free(header); + free(footer); + return MHD_YES; + } + conference = -1; + area = -1; + url_copy = strdup(&url[10]); + + aptr = strtok(url_copy, "/"); + if (aptr != NULL) { + conference = atoi(aptr); + aptr = strtok(NULL, "/"); + if (aptr != NULL) { + area = atoi(aptr); + } + } + free(url_copy); + + if (area != -1 && conference != -1) { + page = www_new_msg(con_inf->user, conference, area); + } else { + free(header); + free(footer); + return MHD_NO; + } + whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1); + sprintf(whole_page, "%s%s%s", header, page, footer); + } else if (strncasecmp(url, "/msgs/", 6) == 0) { + con_inf->user = www_auth_ok(connection, url_); + + if (con_inf->user == NULL) { + www_401(header, footer, connection); + free(header); + free(footer); + return MHD_YES; + } + conference = -1; + area = -1; + msg = -1; + url_copy = strdup(&url[6]); + + aptr = strtok(url_copy, "/"); + if (aptr != NULL) { + conference = atoi(aptr); + aptr = strtok(NULL, "/"); + if (aptr != NULL) { + area = atoi(aptr); + aptr = strtok(NULL, "/"); + if (aptr != NULL) { + msg = atoi(aptr); + } + } + } + free(url_copy); + + val = MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, "skip"); + + if (val != NULL) { + skip = atoi(val); + } else { + skip = 0; + } + + if (conference != -1 && area != -1 && msg == -1) { + page = www_msgs_messagelist(con_inf->user, conference, area, skip); + } else if (conference != -1 && area != -1 && msg != -1) { + page = www_msgs_messageview(con_inf->user, conference, area, msg); + //page = NULL; + } + + + if (page == NULL) { + free(header); + free(footer); + return MHD_NO; + } + whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1); + + sprintf(whole_page, "%s%s%s", header, page, footer); } else if (strncasecmp(url, "/static/", 8) == 0) { // sanatize path if (strstr(url, "/..") != NULL) { @@ -694,6 +806,66 @@ int www_handler(void * cls, struct MHD_Connection * connection, const char * url sprintf(whole_page, "%s%s%s", header, page, footer); + } else if (strcasecmp(url, "/msgs/") == 0 || strcasecmp(url, "/msgs") == 0) { + con_inf->user = www_auth_ok(connection, url_); + + if (con_inf->user == NULL) { + www_401(header, footer, connection); + free(header); + free(footer); + return MHD_YES; + } + + con_inf->pp = MHD_create_post_processor(connection, POSTBUFFERSIZE, iterate_post, (void*) con_inf); + + if (*upload_data_size != 0) { + MHD_post_process (con_inf->pp, upload_data, *upload_data_size); + *upload_data_size = 0; + + return MHD_YES; + } + subj = NULL; + to = NULL; + body = NULL; + replyid = NULL; + + + for (i=0;icount;i++) { + if (strcmp(con_inf->keys[i], "recipient") == 0) { + to = con_inf->values[i]; + } else if (strcmp(con_inf->keys[i], "subject") == 0) { + subj = con_inf->values[i]; + } else if (strcmp(con_inf->keys[i], "body") == 0) { + body = con_inf->values[i]; + } else if (strcmp(con_inf->keys[i], "conference") == 0) { + conference = atoi(con_inf->values[i]); + } else if (strcmp(con_inf->keys[i], "area") == 0) { + area = atoi(con_inf->values[i]); + } else if (strcmp(con_inf->keys[i], "replyid") == 0) { + replyid = con_inf->values[i]; + } + } + if (!www_send_msg(con_inf->user, to, subj, conference, area, replyid, body)) { + page = (char *)malloc(50); + if (page == NULL) { + free(header); + free(footer); + return MHD_NO; + } + sprintf(page, "

Error Sending Message

"); + } else { + page = (char *)malloc(21); + if (page == NULL) { + free(header); + free(footer); + return MHD_NO; + } + sprintf(page, "

Message Sent!

"); + } + whole_page = (char *)malloc(strlen(header) + strlen(page) + strlen(footer) + 1); + + sprintf(whole_page, "%s%s%s", header, page, footer); + } else { free(header); diff --git a/www/header.tpl b/www/header.tpl index c0ecae2..3dcad0f 100644 --- a/www/header.tpl +++ b/www/header.tpl @@ -11,6 +11,7 @@
diff --git a/www/static/style.css b/www/static/style.css index 6cd60f3..e5c4dac 100644 --- a/www/static/style.css +++ b/www/static/style.css @@ -73,6 +73,82 @@ color: #222; } +.conference-list-item { + background-color: #333333; + color: white; + padding: 5px; +} + +.area-list-item { + padding: 5px 0 5px 15px; +} + +.msg-summary-seen { + display: table-row; + width: auto; + clear: both; + background-color: #eee; +} + +.msg-summary { + display: table-row; + width: auto; + clear: both; + background-color: #b2ffb0; +} +.msg-summary-id { + float: left; + display: table-column; + width: 100px; +} + +.msg-summary-subject { + float: left; + display: table-column; + width: 400px; +} + +.msg-summary-from { + float: left; + display: table-column; + width: 200px; +} + +.msg-summary-to { + float: left; + display: table-column; + width: 200px; +} + +.msg-summary-date { + float: left; + display: table-column; + width: 200px; +} + +.msg-view-header { + background-color: #eee; + border: 1px solid #666666; + padding: 5px; + margin-bottom: 10px; +} + +.msg-view-subject { + font-size: xx-large; +} + +.msg-view-from { + color: #222; +} + +.msg-view-to { + color: #222; +} + +.msg-view-date { + color: #222; +} + .menu ul { list-style-type: none; margin: 0; diff --git a/www_email.c b/www_email.c index 9e324ac..6197e90 100644 --- a/www_email.c +++ b/www_email.c @@ -168,7 +168,7 @@ char *www_new_email() { strcat(page, buffer); len += strlen(buffer); - sprintf(buffer, "
\n"); + sprintf(buffer, "To :
\n"); if (len + strlen(buffer) > max_len - 1) { max_len += 4096; page = (char *)realloc(page, max_len); @@ -176,7 +176,7 @@ char *www_new_email() { strcat(page, buffer); len += strlen(buffer); - sprintf(buffer, "
\n"); + sprintf(buffer, "Subject :
\n"); if (len + strlen(buffer) > max_len - 1) { max_len += 4096; page = (char *)realloc(page, max_len); @@ -374,7 +374,11 @@ char *www_email_display(struct user_record *user, int email) { strcat(page, buffer); len += strlen(buffer); - sprintf(buffer, "
\n", subject); + if (strncasecmp(subject, "re:", 3) == 0) { + sprintf(buffer, "Subject :
\n", subject); + } else { + sprintf(buffer, "Subject :
\n", subject); + } if (len + strlen(buffer) > max_len - 1) { max_len += 4096; page = (char *)realloc(page, max_len); diff --git a/www_msgs.c b/www_msgs.c new file mode 100644 index 0000000..3a7c1cf --- /dev/null +++ b/www_msgs.c @@ -0,0 +1,805 @@ +#if defined(ENABLE_WWW) +#include +#include +#include +#include +#include +#include "bbs.h" +#include "jamlib/jam.h" + +extern struct bbs_config conf; + +char *www_msgs_arealist(struct user_record *user) { + char *page; + int max_len; + int len; + char buffer[4096]; + int i, j; + + page = (char *)malloc(4096); + max_len = 4096; + len = 0; + memset(page, 0, 4096); + + sprintf(buffer, "

Message Conferences

\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + for (i=0;isec_level <= user->sec_level) { + sprintf(buffer, "
%s
\n", conf.mail_conferences[i]->name); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + for (j=0;jmail_area_count; j++) { + if (conf.mail_conferences[i]->mail_areas[j]->read_sec_level <= user->sec_level) { + sprintf(buffer, "\n", i, j, conf.mail_conferences[i]->mail_areas[j]->name); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + } + } + } + } + return page; +} + +char *www_msgs_messagelist(struct user_record *user, int conference, int area, int skip) { + struct msg_headers *mhrs; + char *page; + int max_len; + int len; + char buffer[4096]; + int i; + struct tm msg_date; + time_t date; + s_JamBase *jb; + s_JamLastRead jlr; + int skip_f; + int skip_t; + if (conference < 0 || conference >= conf.mail_conference_count || area < 0 || area >= conf.mail_conferences[conference]->mail_area_count) { + return NULL; + } + page = (char *)malloc(4096); + max_len = 4096; + len = 0; + memset(page, 0, 4096); + + sprintf(buffer, "

%s - %s

\n", conf.mail_conferences[conference]->name, conf.mail_conferences[conference]->mail_areas[area]->name); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + + sprintf(buffer, "\n", conference, area); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + mhrs = read_message_headers(conference, area, user); + + if (mhrs == NULL) { + sprintf(buffer, "

No Messages

\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + return page; + } + + sprintf(buffer, "
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + jb = open_jam_base(conf.mail_conferences[conference]->mail_areas[area]->path); + if (!jb) { + free(page); + return NULL; + } + if (JAM_ReadLastRead(jb, user->id, &jlr) == JAM_NO_USER) { + jlr.LastReadMsg = 0; + jlr.HighReadMsg = 0; + } + JAM_CloseMB(jb); + + skip_f = mhrs->msg_count - skip; + skip_t = mhrs->msg_count - skip - 50; + if (skip_t < 0) { + skip_t = 0; + } + + for (i=skip_f -1; i>=skip_t;i--) { + date = (time_t)mhrs->msgs[i]->msg_h->DateWritten; + localtime_r(&date, &msg_date); + if (mhrs->msgs[i]->msg_h->MsgNum > jlr.HighReadMsg) { + sprintf(buffer, "
%d
%s
%s
%.2d:%.2d %.2d-%.2d-%.2d
\n", mhrs->msgs[i]->msg_no + 1, conference, area, mhrs->msgs[i]->msg_h->MsgNum, mhrs->msgs[i]->subject, mhrs->msgs[i]->from, mhrs->msgs[i]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } else { + sprintf(buffer, "
%d
%s
%s
%.2d:%.2d %.2d-%.2d-%.2d
\n", mhrs->msgs[i]->msg_no + 1, conference, area, mhrs->msgs[i]->msg_h->MsgNum, mhrs->msgs[i]->subject, mhrs->msgs[i]->from, mhrs->msgs[i]->to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + } + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + } + sprintf(buffer, "
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + if (skip > 0) { + if (skip - 50 < 0) { + sprintf(buffer, "\n", conference, area); + } else { + sprintf(buffer, "\n", conference, area, skip - 50); + } + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + } + + if (skip + 50 <= mhrs->msg_count) { + sprintf(buffer, "\n", conference, area, skip + 50); + } + + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + free_message_headers(mhrs); + return page; +} + +char *www_msgs_messageview(struct user_record *user, int conference, int area, int msg) { + s_JamBase *jb; + s_JamMsgHeader jmh; + s_JamSubPacket* jsp; + s_JamSubfield jsf; + s_JamLastRead jlr; + s_JamBaseHeader jbh; + + char *subject = NULL; + char *from = NULL; + char *to = NULL; + char *daddress = NULL; + char *oaddress = NULL; + char *msgid = NULL; + char *replyid = NULL; + char *body = NULL; + int z; + struct tm msg_date; + time_t date; + char *page; + int max_len; + int len; + char buffer[4096]; + + if (conference < 0 || conference >= conf.mail_conference_count || area < 0 || area >= conf.mail_conferences[conference]->mail_area_count) { + return NULL; + } + + if (conf.mail_conferences[conference]->sec_level <= user->sec_level && conf.mail_conferences[conference]->mail_areas[area]->read_sec_level <= user->sec_level) { + jb = open_jam_base(conf.mail_conferences[conference]->mail_areas[area]->path); + if (!jb) { + return NULL; + } + + JAM_ReadMBHeader(jb, &jbh); + + memset(&jmh, 0, sizeof(s_JamMsgHeader)); + z = JAM_ReadMsgHeader(jb, msg - 1, &jmh, &jsp); + if (z != 0) { + JAM_CloseMB(jb); + return NULL; + } + if (jmh.Attribute & MSG_DELETED) { + JAM_DelSubPacket(jsp); + JAM_CloseMB(jb); + return NULL; + } + + for (z=0;zNumFields;z++) { + if (jsp->Fields[z]->LoID == JAMSFLD_SUBJECT) { + subject = (char *)malloc(jsp->Fields[z]->DatLen + 1); + memset(subject, 0, jsp->Fields[z]->DatLen + 1); + memcpy(subject, jsp->Fields[z]->Buffer, jsp->Fields[z]->DatLen); + } + if (jsp->Fields[z]->LoID == JAMSFLD_SENDERNAME) { + from = (char *)malloc(jsp->Fields[z]->DatLen + 1); + memset(from, 0, jsp->Fields[z]->DatLen + 1); + memcpy(from, jsp->Fields[z]->Buffer, jsp->Fields[z]->DatLen); + } + if (jsp->Fields[z]->LoID == JAMSFLD_RECVRNAME) { + to = (char *)malloc(jsp->Fields[z]->DatLen + 1); + memset(to, 0, jsp->Fields[z]->DatLen + 1); + memcpy(to, jsp->Fields[z]->Buffer, jsp->Fields[z]->DatLen); + } + if (jsp->Fields[z]->LoID == JAMSFLD_DADDRESS) { + daddress = (char *)malloc(jsp->Fields[z]->DatLen + 1); + memset(daddress, 0, jsp->Fields[z]->DatLen + 1); + memcpy(daddress, jsp->Fields[z]->Buffer, jsp->Fields[z]->DatLen); + } + if (jsp->Fields[z]->LoID == JAMSFLD_OADDRESS) { + oaddress = (char *)malloc(jsp->Fields[z]->DatLen + 1); + memset(oaddress, 0, jsp->Fields[z]->DatLen + 1); + memcpy(oaddress, jsp->Fields[z]->Buffer, jsp->Fields[z]->DatLen); + } + 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) { + replyid = (char *)malloc(jsp->Fields[z]->DatLen + 1); + memset(replyid, 0, jsp->Fields[z]->DatLen + 1); + memcpy(replyid, jsp->Fields[z]->Buffer, jsp->Fields[z]->DatLen); + } + } + JAM_DelSubPacket(jsp); + + if (jmh.Attribute & MSG_PRIVATE) { + if (!msg_is_to(user, to, daddress, conf.mail_conferences[conference]->nettype, conf.mail_conferences[conference]->realnames, conference) && + !msg_is_from(user, from, oaddress, conf.mail_conferences[conference]->nettype, conf.mail_conferences[conference]->realnames, conference)) { + + if (subject != NULL) { + free(subject); + } + if (from != NULL) { + free(from); + } + if (to != NULL) { + free(to); + } + if (oaddress != NULL) { + free(oaddress); + } + if (daddress != NULL) { + free(daddress); + } + if (msgid != NULL) { + free(msgid); + } + if (replyid != NULL) { + free(replyid); + } + JAM_CloseMB(jb); + return NULL; + } + } + body = (char *)malloc(jmh.TxtLen); + + JAM_ReadMsgText(jb, jmh.TxtOffset,jmh.TxtLen, (char *)body); + + if (JAM_ReadLastRead(jb, user->id, &jlr) == JAM_NO_USER) { + jlr.UserCRC = JAM_Crc32(user->loginname, strlen(user->loginname)); + jlr.UserID = user->id; + jlr.HighReadMsg = msg; + } + + jlr.LastReadMsg = msg; + if (jlr.HighReadMsg < msg) { + jlr.HighReadMsg = msg; + } + + JAM_WriteLastRead(jb, user->id, &jlr); + JAM_CloseMB(jb); + + page = (char *)malloc(4096); + max_len = 4096; + len = 0; + memset(page, 0, 4096); + + sprintf(buffer, "

%s - %s

\n", conf.mail_conferences[conference]->name, conf.mail_conferences[conference]->mail_areas[area]->name); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + + sprintf(buffer, "
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "
%s
\n", subject); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + if (conf.mail_conferences[conference]->mail_areas[area]->type != TYPE_LOCAL_AREA) { + sprintf(buffer, "
From: %s (%s)
\n", from, oaddress); + } else { + sprintf(buffer, "
From: %s
\n", from); + } + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "
To: %s
\n", to); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + date = (time_t)jmh.DateWritten; + localtime_r(&date, &msg_date); + + sprintf(buffer, "
Date: %.2d:%.2d %.2d-%.2d-%.2d
\n", msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + + for (z=0;z"); + } else { + sprintf(buffer, "%c", body[z]); + } + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + } + free(body); + + sprintf(buffer, "
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + if (conf.mail_conferences[conference]->mail_areas[area]->write_sec_level <= user->sec_level && conf.mail_conferences[conference]->mail_areas[area]->type != TYPE_NETMAIL_AREA) { + sprintf(buffer, "

Reply

\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "\n", conference); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + sprintf(buffer, "\n", area); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "\n", msgid); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "To :
\n", from); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + if (strncasecmp(subject, "re:", 3) == 0) { + sprintf(buffer, "Subject :
\n", subject); + } else { + sprintf(buffer, "Subject :
\n", subject); + } + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "\n
"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "\n
"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + + sprintf(buffer, "
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + } + if (subject != NULL) { + free(subject); + } + if (from != NULL) { + free(from); + } + if (to != NULL) { + free(to); + } + if (oaddress != NULL) { + free(oaddress); + } + if (daddress != NULL) { + free(daddress); + } + if (msgid != NULL) { + free(msgid); + } + if (replyid != NULL) { + free(replyid); + } + return page; + } else { + return NULL; + } +} + +int www_send_msg(struct user_record *user, char *to, char *subj, int conference, int area, char *replyid, char *body) { + s_JamBase *jb; + s_JamMsgHeader jmh; + s_JamSubPacket* jsp; + s_JamSubfield jsf; + s_JamLastRead jlr; + s_JamBaseHeader jbh; + int z; + int sem_fd; + char *page; + int max_len; + int len; + char buffer[256]; + char timestr[17]; + char *body2; + char *tagline; + struct utsname name; + if (conference < 0 || conference >= conf.mail_conference_count || area < 0 || area >= conf.mail_conferences[conference]->mail_area_count) { + return 0; + } + if (conf.mail_conferences[conference]->mail_areas[area]->write_sec_level <= user->sec_level && conf.mail_conferences[conference]->mail_areas[area]->type != TYPE_NETMAIL_AREA) { + jb = open_jam_base(conf.mail_conferences[conference]->mail_areas[area]->path); + if (!jb) { + return 0; + } + + JAM_ClearMsgHeader( &jmh ); + jmh.DateWritten = (uint32_t)time(NULL); + jmh.Attribute |= MSG_LOCAL; + + if (conf.mail_conferences[conference]->realnames == 0) { + if (conf.mail_conferences[conference]->nettype == NETWORK_WWIV) { + sprintf(buffer, "%s #%d @%d", user->loginname, user->id, conf.mail_conferences[conference]->wwivnode); + } else { + strcpy(buffer, user->loginname); + } + } else { + if (conf.mail_conferences[conference]->nettype == NETWORK_WWIV) { + sprintf(buffer, "%s #%d @%d (%s)", user->loginname, user->id, conf.mail_conferences[conference]->wwivnode, user->firstname); + } else { + sprintf(buffer, "%s %s", user->firstname, user->lastname); + } + } + jsp = JAM_NewSubPacket(); + + jsf.LoID = JAMSFLD_SENDERNAME; + jsf.HiID = 0; + jsf.DatLen = strlen(buffer); + jsf.Buffer = (char *)buffer; + JAM_PutSubfield(jsp, &jsf); + + jsf.LoID = JAMSFLD_RECVRNAME; + jsf.HiID = 0; + jsf.DatLen = strlen(to); + jsf.Buffer = (char *)to; + JAM_PutSubfield(jsp, &jsf); + + jsf.LoID = JAMSFLD_SUBJECT; + jsf.HiID = 0; + jsf.DatLen = strlen(subj); + jsf.Buffer = (char *)subj; + JAM_PutSubfield(jsp, &jsf); + + if (conf.mail_conferences[conference]->mail_areas[area]->type == TYPE_ECHOMAIL_AREA) { + jmh.Attribute |= MSG_TYPEECHO; + + if (conf.mail_conferences[conference]->nettype == NETWORK_FIDO) { + if (conf.mail_conferences[conference]->fidoaddr->point) { + sprintf(buffer, "%d:%d/%d.%d", conf.mail_conferences[conference]->fidoaddr->zone, + conf.mail_conferences[conference]->fidoaddr->net, + conf.mail_conferences[conference]->fidoaddr->node, + conf.mail_conferences[conference]->fidoaddr->point); + } else { + sprintf(buffer, "%d:%d/%d", conf.mail_conferences[conference]->fidoaddr->zone, + conf.mail_conferences[conference]->fidoaddr->net, + conf.mail_conferences[conference]->fidoaddr->node); + } + jsf.LoID = JAMSFLD_OADDRESS; + jsf.HiID = 0; + jsf.DatLen = strlen(buffer); + jsf.Buffer = (char *)buffer; + JAM_PutSubfield(jsp, &jsf); + + snprintf(timestr, 16, "%016lx", time(NULL)); + + sprintf(buffer, "%d:%d/%d.%d %s", conf.mail_conferences[conference]->fidoaddr->zone, + conf.mail_conferences[conference]->fidoaddr->net, + conf.mail_conferences[conference]->fidoaddr->node, + conf.mail_conferences[conference]->fidoaddr->point, + ×tr[strlen(timestr) - 8]); + + jsf.LoID = JAMSFLD_MSGID; + jsf.HiID = 0; + jsf.DatLen = strlen(buffer); + jsf.Buffer = (char *)buffer; + JAM_PutSubfield(jsp, &jsf); + jmh.MsgIdCRC = JAM_Crc32(buffer, strlen(buffer)); + + 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(buffer, strlen(replyid)); + } + } + } + while (1) { + z = JAM_LockMB(jb, 100); + if (z == 0) { + break; + } else if (z == JAM_LOCK_FAILED) { + sleep(1); + } else { + JAM_CloseMB(jb); + return 0; + } + } + if (z != 0) { + JAM_CloseMB(jb); + return 0; + } + + if (conf.mail_conferences[conference]->tagline != NULL) { + tagline = conf.mail_conferences[conference]->tagline; + } else { + tagline = conf.default_tagline; + } + + uname(&name); + + if (conf.mail_conferences[conference]->nettype == NETWORK_FIDO) { + if (conf.mail_conferences[conference]->fidoaddr->point == 0) { + snprintf(buffer, 256, "\r--- MagickaBBS v%d.%d%s (%s/%s)\r * Origin: %s (%d:%d/%d)\r", VERSION_MAJOR, VERSION_MINOR, VERSION_STR, name.sysname, name.machine, tagline, conf.mail_conferences[conference]->fidoaddr->zone, + conf.mail_conferences[conference]->fidoaddr->net, + conf.mail_conferences[conference]->fidoaddr->node); + } else { + snprintf(buffer, 256, "\r--- MagickaBBS v%d.%d%s (%s/%s)\r * Origin: %s (%d:%d/%d.%d)\r", VERSION_MAJOR, VERSION_MINOR, VERSION_STR, name.sysname, name.machine, tagline, conf.mail_conferences[conference]->fidoaddr->zone, + conf.mail_conferences[conference]->fidoaddr->net, + conf.mail_conferences[conference]->fidoaddr->node, + conf.mail_conferences[conference]->fidoaddr->point); + } + } else { + snprintf(buffer, 256, "\r--- MagickaBBS v%d.%d%s (%s/%s)\r * Origin: %s \r", VERSION_MAJOR, VERSION_MINOR, VERSION_STR, name.sysname, name.machine, tagline); + } + body2 = (char *)malloc(strlen(body) + 2 + strlen(buffer)); + memset(body2, 0, strlen(body) + 2 + strlen(buffer)); + + for (z =0;z < strlen(body); z++) { + if (body[z] == '\n') { + body2[z] = '\r'; + } else { + body2[z] = body[z]; + } + } + strcat(body2, buffer); + + if (JAM_AddMessage(jb, &jmh, jsp, (char *)body2, strlen(body2))) { + + } else { + if (conf.mail_conferences[conference]->mail_areas[area]->type == TYPE_ECHOMAIL_AREA) { + if (conf.echomail_sem != NULL) { + sem_fd = open(conf.echomail_sem, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH); + close(sem_fd); + } + } + } + + free(body2); + + JAM_UnlockMB(jb); + + JAM_DelSubPacket(jsp); + JAM_CloseMB(jb); + + return 1; + } +} + +char *www_new_msg(struct user_record *user, int conference, int area) { + char *page; + int max_len; + int len; + char buffer[4096]; + + page = (char *)malloc(4096); + max_len = 4096; + len = 0; + memset(page, 0, 4096); + + sprintf(buffer, "

New Message

\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "\n", conference); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + sprintf(buffer, "\n", area); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "To :
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "Subject :
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "\n
"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + sprintf(buffer, "\n
"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + + sprintf(buffer, "
\n"); + if (len + strlen(buffer) > max_len - 1) { + max_len += 4096; + page = (char *)realloc(page, max_len); + } + strcat(page, buffer); + len += strlen(buffer); + + return page; +} + +#endif