jcs
/subtext
/amendments
/359
board: Move echomail message importing here
jcs made amendment 359 about 1 year ago
--- board.c Wed Mar 1 22:00:33 2023
+++ board.c Sat Mar 4 22:32:17 2023
@@ -22,6 +22,7 @@
#include "subtext.h"
#include "ansi.h"
#include "board.h"
+#include "logger.h"
#include "user.h"
#define POSTS_PER_PAGE 20
@@ -339,7 +340,7 @@ board_list_posts(struct session *s, struct board *boar
strftime(time, sizeof(time), "%b %d", localtime(&fpost.time));
- session_printf(s, "%s%2ld %c %s %- 10s {{#}}%.40s%s\r\n",
+ session_printf(s, "%s%2ld %c %s %-10.10s {{#}}%.40s%s\r\n",
true ? "" : ansi(s, ANSI_BOLD, ANSI_END),
n + 1,
true ? ' ' : 'N',
@@ -411,7 +412,7 @@ board_list_posts(struct session *s, struct board *boar
indent_s[j + 2] = '>';
indent_s[j + 3] = '\0';
}
- session_printf(s, "%s%2ld %c %s %- 10s %s{{#}}%.40s%s\r\n",
+ session_printf(s, "%s%2ld %c %s %-10.10s %s{{#}}%.40s%s\r\n",
true ? "" : ansi(s, ANSI_BOLD, ANSI_END),
n + 1,
true ? ' ' : 'N',
@@ -627,7 +628,7 @@ board_post_read(struct session *s, struct board *board
size_t size;
short ret = POST_READ_RETURN_DONE;
char c;
- char *data;
+ char *data, *subject;
short cc;
bool done = false, show_help = false;
@@ -721,9 +722,14 @@ board_post_read(struct session *s, struct board *board
snprintf(prompt, sizeof(prompt), "Boards:%s:%d", board->name, idx);
+ if (board->fidonet_area[0])
+ subject = fpost.subject;
+ else
+ subject = thread.subject;
+
while (!done && !s->ending) {
- c = session_menu(s, thread.subject, prompt, dopts,
- nitems(opts), show_help, NULL, NULL);
+ c = session_menu(s, subject, prompt, dopts, nitems(opts),
+ show_help, NULL, NULL);
show_help = false;
switch (c) {
@@ -778,6 +784,7 @@ board_post_read(struct session *s, struct board *board
done = true;
break;
case 'q':
+ ret = POST_READ_RETURN_DONE;
done = true;
break;
case '?':
@@ -1228,4 +1235,140 @@ write_out:
else
*sorted_ids = post_ids;
return npost_ids;
-}
+}
+
+short
+board_ingest_fidopkt(struct board *board, struct fidopkt *fidopkt)
+{
+ struct board_fidonet_msgid_cache {
+ unsigned long id;
+ struct fidopkt_msgid msgid;
+ } *msgid_cache = NULL;
+ struct bile_object *o;
+ struct board_fidonet_post post;
+ struct fidopkt_msgid msgid;
+ unsigned long *post_ids;
+ char *pdata;
+ size_t asize, cache_size, psize, npost_ids;
+ ssize_t count;
+ short n, ret, bret;
+ bool dirty_cache = false;
+
+ msgid = fidopkt->msgid;
+
+ o = bile_find(board->bile, BOARD_FIDONET_MSGID_CACHE_RTYPE, 1);
+ if (o) {
+ /* allocate its size plus one entry that we may add */
+ asize = o->size + sizeof(struct board_fidonet_msgid_cache);
+ msgid_cache = malloc(asize);
+ if (msgid_cache == NULL) {
+ logger_printf("[board] board_ingest_fidopkt: malloc(%ld) failed",
+ asize);
+ return -1;
+ }
+ bile_read(board->bile, o->type, o->id, msgid_cache, o->size);
+ npost_ids = o->size / sizeof(struct board_fidonet_msgid_cache);
+ xfree(&o);
+ } else {
+ npost_ids = bile_ids_by_type(board->bile, BOARD_FIDONET_POST_RTYPE,
+ &post_ids);
+ msgid_cache = calloc(sizeof(struct board_fidonet_msgid_cache),
+ npost_ids + 1);
+ if (msgid_cache == NULL) {
+ logger_printf("[board] board_ingest_fidopkt: calloc failed");
+ return -1;
+ }
+ for (n = 0; n < npost_ids; n++) {
+ /* only read as far as we have to */
+ bile_read(board->bile, BOARD_FIDONET_POST_RTYPE, post_ids[n],
+ &post, offsetof(struct board_fidonet_post, msgid) +
+ member_size(struct board_fidonet_post, msgid));
+
+ msgid_cache[n].id = post.id;
+ memcpy(&msgid_cache[n].msgid, &post.msgid,
+ sizeof(post.msgid));
+ }
+ dirty_cache = true;
+ }
+
+ uthread_yield();
+
+ for (n = 0; n < npost_ids; n++) {
+ if (memcmp(&msgid_cache[n].msgid, &msgid, sizeof(msgid)) == 0) {
+ logger_printf("[board] already have fidonet msg %s in %s "
+ "(%ld), skipping", fidopkt->msgid_orig, board->name,
+ msgid_cache[n].id);
+ ret = 0;
+ goto done;
+ }
+ }
+
+ memset(&post, 0, sizeof(post));
+ post.time = fidopkt->time; /* TODO: add/sub local offset */
+ post.body_size = fidopkt->message_len + 1;
+ post.body = fidopkt->message;
+ strlcpy(post.reply, fidopkt->reply, sizeof(post.reply));
+ strlcpy(post.from, fidopkt->from, sizeof(post.from));
+ strlcpy(post.subject, fidopkt->subject, sizeof(post.subject));
+ strlcpy(post.to, fidopkt->to, sizeof(post.to));
+ strlcpy(post.origin, fidopkt->origin, sizeof(post.origin));
+ strlcpy(post.msgid_orig, fidopkt->msgid_orig, sizeof(post.msgid_orig));
+ post.msgid = msgid;
+
+ post.id = bile_next_id(board->bile, BOARD_FIDONET_POST_RTYPE);
+ if (!post.id) {
+ logger_printf("[board] failed get next id for %s", board->name);
+ ret = -1;
+ goto done;
+ }
+
+ bret = bile_marshall_object(board->bile,
+ board_fidonet_post_object_fields, nboard_fidonet_post_object_fields,
+ &post, &pdata, &psize);
+ if (bret != 0 || psize == 0) {
+ logger_printf("[board] failed to marshall new post %s %s",
+ fidopkt->area, fidopkt->msgid_orig);
+ ret = -1;
+ goto done;
+ }
+ if (bile_write(board->bile, BOARD_FIDONET_POST_RTYPE, post.id, pdata,
+ psize) != psize) {
+ logger_printf("[fidopkt] failed to save new post %s %s: %d",
+ fidopkt->area, fidopkt->msgid_orig, bile_error(board->bile));
+ ret = -1;
+ xfree(&pdata);
+ goto done;
+ }
+ xfree(&pdata);
+
+ ret = 1;
+
+ /* we already allocated one empty space at the end of the cache */
+ msgid_cache[npost_ids].id = post.id;
+ memcpy(&msgid_cache[npost_ids].msgid, &post.msgid, sizeof(post.msgid));
+ npost_ids++;
+ dirty_cache = true;
+
+ /* force rebuild of board ID cache the next time someone views it */
+ bile_delete(board->bile, BOARD_SORTED_IDS_RTYPE, 1,
+ BILE_DELETE_FLAG_PURGE);
+
+ logger_printf("[board] imported %s %s as %ld",
+ fidopkt->area, fidopkt->msgid_orig, post.id);
+ uthread_yield();
+
+done:
+ if (dirty_cache) {
+ cache_size = npost_ids * sizeof(struct board_fidonet_msgid_cache);
+ if (bile_write(board->bile, BOARD_FIDONET_MSGID_CACHE_RTYPE, 1,
+ msgid_cache, cache_size) != cache_size) {
+ logger_printf("[board] failed to save msgid cache for %s: %d",
+ fidopkt->area, bile_error(board->bile));
+ ret = -1;
+ }
+ }
+ if (msgid_cache != NULL)
+ free(msgid_cache);
+
+ return ret;
+}
--- board.h Tue Feb 28 15:25:18 2023
+++ board.h Fri Mar 3 15:56:50 2023
@@ -41,14 +41,6 @@ extern const size_t nboard_fields;
extern const struct bile_object_field board_object_fields[];
extern const size_t nboard_object_fields;
-struct board_fidonet_msgid {
- unsigned long id;
- u_int16_t zone;
- u_int16_t net;
- u_int16_t node;
- u_int16_t point;
-};
-
struct board_post {
unsigned long id;
unsigned long thread_id;
@@ -64,7 +56,7 @@ extern const size_t nboard_post_object_fields;
struct board_fidonet_post {
unsigned long id;
- struct board_fidonet_msgid msgid;
+ struct fidopkt_msgid msgid;
time_t time;
char from[32];
char subject[80];
@@ -99,5 +91,6 @@ void board_delete_fidonet_post(struct session *s, stru
struct board_fidonet_post *post);
size_t board_index_sorted_post_ids(struct board *board,
unsigned long **sorted_ids);
+short board_ingest_fidopkt(struct board *board, struct fidopkt *fidopkt);
#endif