AmendHub

Download:

jcs

/

subtext

/

amendments

/

323

binkp: Import unseen messages into boards with matching fidonet_area

This is quite slow, but I'll work on speeding it up

jcs made amendment 323 about 1 year ago
--- binkp.c Thu Feb 23 09:05:28 2023 +++ binkp.c Sat Feb 25 17:57:57 2023 @@ -20,6 +20,7 @@ #include <stdio.h> #include <string.h> #include "binkp.h" +#include "board.h" #include "fidopkt.h" #include "logger.h" #include "subtext.h" @@ -29,6 +30,7 @@ static struct binkp_connection *binkpc = NULL; static Str255 binkp_dir; +static short binkp_fidopkt_skipped, binkp_fidopkt_imported; void binkp_fetch(void); void binkp_ingest(void); @@ -55,16 +57,19 @@ binkp_thread(struct uthread *uthread, void *arg) } for (;;) { + if (db->config.binkp_hostname[0] != '\0' && + db->config.binkp_port != 0) + binkp_fetch(); + + binkp_ingest(); + if (db->config.binkp_hostname[0] == '\0' || db->config.binkp_port == 0) + /* no new ones are likely to show up, then */ break; - - binkp_fetch(); - binkp_ingest(); - + if (!db->config.binkp_interval_seconds) break; - uthread_msleep(1000UL * db->config.binkp_interval_seconds); } } @@ -525,6 +530,7 @@ binkp_ingest(void) short error, n; Str255 file_name, abs_path; short dir_id; + unsigned long started = Time; fpb->ioVRefNum = 0; fpb->ioNamePtr = binkp_dir; @@ -549,11 +555,26 @@ binkp_ingest(void) snprintf((char *)abs_path, sizeof(abs_path), "%s:%s", binkp_dir, PtoCstr(file_name)); CtoPstr(binkp_dir); +#ifdef BINKP_DEBUG logger_printf("[binkp] scanning zip file %s", (char *)abs_path); +#endif + binkp_fidopkt_skipped = 0; + binkp_fidopkt_imported = 0; + CtoPstr(abs_path); zip_read_file(abs_path, binkp_zip_decider, binkp_zip_processor); + + logger_printf("[binkp] %s: imported %d, skipped %d", + (char *)file_name, binkp_fidopkt_imported, + binkp_fidopkt_skipped); + + if ((error = FSDelete(abs_path, 0)) != 0) + logger_printf("[binkp] failed deleting %s: %d", + PtoCstr(abs_path), error); } + + logger_printf("[binkp] done importing in %ld sec(s)", Time - started); } bool @@ -571,12 +592,101 @@ void binkp_zip_processor(char *filename, size_t size, unsigned char *data) { struct fidopkt *fidopkt; + struct bile_object *o; + struct board *board = NULL; + struct board_post post = { 0 }; + struct board_post_fidonet_msgid fidonet_msgid; + struct board_thread thread = { 0 }; + char *pdata; + size_t psize; + ssize_t count; + short n; uthread_yield(); - + fidopkt = fidopkt_parse(filename, (char *)data, size); if (fidopkt == NULL) return; + + for (n = 0; n < db->nboards; n++) { + if (db->boards[n].fidonet_area[0] && + strcmp(fidopkt->area, db->boards[n].fidonet_area) == 0) { + board = &db->boards[n]; + break; + } + } + + if (!board) { +#ifdef BINKP_DEBUG + logger_printf("[fidopkt] no local board for %s, skipping", + fidopkt->area); +#endif + binkp_fidopkt_skipped++; + goto done; + } + + fidonet_msgid.id = fidopkt->msgid; + fidonet_msgid.zone = fidopkt->msgid_zone; + fidonet_msgid.net = fidopkt->msgid_net; + fidonet_msgid.node = fidopkt->msgid_node; + fidonet_msgid.point = fidopkt->msgid_point; + + /* TODO: add an index of id->msgid to avoid searching every message */ + /* search backwards to check newest messages first */ + count = bile_count_by_type(board->bile, BOARD_POST_RTYPE); + for (; count > 0 && (o = bile_get_nth_of_type(board->bile, + count - 1, BOARD_POST_RTYPE)); count--) { + psize = bile_read_alloc(board->bile, o->type, o->id, &pdata); + bile_unmarshall_object(board->bile, board_post_object_fields, + nboard_post_object_fields, pdata, psize, &post, sizeof(post), + false, "binkp post"); + xfree(&o); + xfree(&pdata); + if (memcmp(&post.fidonet_msgid, &fidonet_msgid, + sizeof(post.fidonet_msgid)) == 0) { +#ifdef BINKP_DEBUG + logger_printf("[fidopkt] already have %s in %s, skipping", + fidopkt->msgid_orig, board->name); +#endif + binkp_fidopkt_skipped++; + 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.via, "FidoNet", sizeof(post.via)); + strlcpy(post.fidonet_reply, fidopkt->reply, sizeof(post.fidonet_reply)); + strlcpy(post.fidonet_from, fidopkt->from, sizeof(post.fidonet_from)); + strlcpy(post.fidonet_to, fidopkt->to, sizeof(post.fidonet_to)); + strlcpy(post.fidonet_origin, fidopkt->origin, + sizeof(post.fidonet_origin)); + strlcpy(post.fidonet_msgid_orig, fidopkt->msgid_orig, + sizeof(post.fidonet_msgid_orig)); + memcpy(&post.fidonet_msgid, &fidonet_msgid, + sizeof(post.fidonet_msgid)); + + /* + * TODO: find parent and set post.parent_post_id and/or join existing + * thread + */ + thread.subject = fidopkt->subject; + thread.subject_size = strlen(fidopkt->subject) + 1; + + if (board_post_create(board, &thread, &post) == 0) { +#ifdef BINKP_DEBUG + logger_printf("[fidopkt] imported %s %s as %ld", + fidopkt->area, fidopkt->msgid_orig, post.id); +#endif + binkp_fidopkt_imported++; + } else { + logger_printf("[fidopkt] failed importing %s %s", + fidopkt->area, fidopkt->msgid_orig); + } + +done: fidopkt_free(&fidopkt); } --- board.c Wed Feb 22 21:31:49 2023 +++ board.c Sat Feb 25 15:41:11 2023 @@ -51,6 +51,9 @@ const struct struct_field board_fields[] = { { "Days of Retention", CONFIG_TYPE_SHORT, offsetof(struct board, retention_days), 0, USHRT_MAX }, + { "FidoNet Area Name", CONFIG_TYPE_STRING, + offsetof(struct board, fidonet_area), + 0, member_size(struct board, description) }, }; const size_t nboard_fields = nitems(board_fields); @@ -71,6 +74,8 @@ const struct bile_object_field board_object_fields[] = member_size(struct board, last_post_at), -1 }, { offsetof(struct board, post_count), member_size(struct board, post_count), -1 }, + { offsetof(struct board, fidonet_area), + member_size(struct board, fidonet_area), -1 }, }; const size_t nboard_object_fields = nitems(board_object_fields); @@ -91,6 +96,18 @@ const struct bile_object_field board_post_object_field member_size(struct board_post, parent_post_id), -1 }, { offsetof(struct board_post, via), member_size(struct board_post, via), -1 }, + { offsetof(struct board_post, fidonet_reply), + member_size(struct board_post, fidonet_reply), -1 }, + { offsetof(struct board_post, fidonet_from), + member_size(struct board_post, fidonet_from), -1 }, + { offsetof(struct board_post, fidonet_to), + member_size(struct board_post, fidonet_to), -1 }, + { offsetof(struct board_post, fidonet_origin), + member_size(struct board_post, fidonet_origin), -1 }, + { offsetof(struct board_post, fidonet_msgid_orig), + member_size(struct board_post, fidonet_msgid_orig), -1 }, + { offsetof(struct board_post, fidonet_msgid), + member_size(struct board_post, fidonet_msgid), -1 }, }; const size_t nboard_post_object_fields = nitems(board_post_object_fields); @@ -121,10 +138,6 @@ short board_post_read(struct session *s, struct board unsigned long id, short idx); size_t board_find_post_ids(struct board *board, size_t *npost_ids, unsigned long **post_ids, size_t offset, size_t limit); -short board_post_create(struct board *board, struct board_thread *thread, - struct board_post *post); -void board_delete_post(struct session *s, struct board *board, - struct board_post *post, struct board_thread *thread); void board_show(struct session *s, short id) @@ -138,7 +151,7 @@ board_show(struct session *s, short id) { 'q', "QqXx", "Return to main menu" }, { '?', "?", "List menu options" }, }; - char prompt[7 + BOARD_NAME_LENGTH]; + char prompt[7 + member_size(struct board, name)]; struct board *board = NULL; size_t n, nall_post_ids, page, pages, npost_ids; unsigned long *post_ids = NULL; @@ -323,7 +336,10 @@ board_list_posts(struct session *s, struct board *boar indent_parent_ids[j] = 0; } - user = user_username(post.sender_user_id); + if (board->fidonet_area[0]) + user = NULL; + else + user = user_username(post.sender_user_id); strftime(time, sizeof(time), "%b %d", localtime(&post.time)); if (post.parent_post_id == 0) { @@ -354,12 +370,13 @@ 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 %- 10s %s{{#}}%.40s%s\r\n", true ? "" : ansi(s, ANSI_BOLD, ANSI_END), n + 1, true ? ' ' : 'N', time, - user ? user->username : "(unknown)", + user ? user->username : + (post.fidonet_from[0] ? post.fidonet_from : "(unknown)"), post.parent_post_id != 0 && n == 0 ? "Re: " : "", post.parent_post_id == 0 || n == 0 ? thread.subject : indent_s, true ? "" : ansi(s, ANSI_RESET, ANSI_END)); @@ -547,7 +564,7 @@ board_post_read(struct session *s, struct board *board { 'q', "QqXx", "Return to threads" }, { '?', "?", "List these options" }, }; - char time[32], prompt[7 + BOARD_NAME_LENGTH + 8]; + char time[32], prompt[7 + member_size(struct board, name) + 8]; struct board_thread thread; struct board_post post; struct username_cache *sender; @@ -591,12 +608,21 @@ board_post_read(struct session *s, struct board *board strftime(time, sizeof(time), "%Y-%m-%d %H:%M:%S", localtime(&post.time)); - session_printf(s, "{{B}}From:{{/B}} %s", - sender ? sender->username : "(unknown)"); - if (post.via[0]) - session_printf(s, " (via %s)", post.via); - session_printf(s, "\r\n"); - session_printf(s, "{{B}}To:{{/B}} %s\r\n", board->name); + if (board->fidonet_area[0]) { + session_printf(s, "{{B}}From:{{/B}} %s\r\n", + post.fidonet_from); + session_printf(s, "{{B}}Origin:{{/B}} %s\r\n", + post.fidonet_origin); + session_printf(s, "{{B}}To:{{/B}} %s@%s\r\n", + post.fidonet_to, board->name); + } else { + session_printf(s, "{{B}}From:{{/B}} %s", + sender ? sender->username : "(unknown)"); + if (post.via[0]) + session_printf(s, " (via %s)", post.via); + session_printf(s, "\r\n"); + session_printf(s, "{{B}}To:{{/B}} %s\r\n", board->name); + } session_printf(s, "{{B}}Date:{{/B}} %s %s\r\n", time, db->config.timezone); session_printf(s, "{{B}}Subject:{{/B}}{{#}} %s%s\r\n", @@ -801,7 +827,8 @@ board_post_create(struct board *board, struct board_th } post->id = bile_next_id(board->bile, BOARD_POST_RTYPE); - post->time = Time; + if (!post->time) + post->time = Time; ret = bile_marshall_object(board->bile, board_post_object_fields, nboard_post_object_fields, post, &data, &size, @@ -820,7 +847,8 @@ board_post_create(struct board *board, struct board_th } xfree(&data); - thread->last_post_at = post->time; + if (post->time > thread->last_post_at) + thread->last_post_at = post->time; thread->nposts++; thread->post_ids = xreallocarray(thread->post_ids, thread->nposts, sizeof(long)); @@ -828,10 +856,11 @@ board_post_create(struct board *board, struct board_th thread->nposts, sizeof(long)); /* - * Add new post id to thread post_ids, but put it in the right place - * so that reading post_ids will present the tree in order. Walk - * parent_post_ids and find the first match of our parent, then insert - * our new post there. This puts newest replies at the top. + * Add new post id to thread post_ids, but put it in the right + * place so that reading post_ids will present the tree in order. + * Walk parent_post_ids and find the first match of our parent, + * then insert our new post there. This puts newest replies at + * the top. */ insert = thread->nposts - 1; @@ -865,7 +894,7 @@ board_post_create(struct board *board, struct board_th goto done; } xfree(&data); - + bile_flush(board->bile, true); done: --- board.h Tue Nov 8 13:02:37 2022 +++ board.h Sat Feb 25 17:22:21 2023 @@ -18,22 +18,37 @@ #define __BOARD_H__ #include <stddef.h> +#include "fidopkt.h" #include "session.h" #include "settings.h" +struct board_post_fidonet_msgid { + unsigned long id; + u_int16_t zone; + u_int16_t net; + u_int16_t node; + u_int16_t point; +}; + +struct board_fidonet_msgid_id_map_entry { + struct board_post_fidonet_msgid msgid; + unsigned long id; +}; + struct board { unsigned long id; -#define BOARD_NAME_LENGTH 32 - char name[BOARD_NAME_LENGTH]; -#define BOARD_DESCR_LENGTH 100 - char description[BOARD_DESCR_LENGTH]; + char name[32]; + char description[100]; bool restricted_posting; bool restricted_viewing; unsigned short retention_days; unsigned long last_post_at; unsigned long post_count; + char fidonet_area[32]; struct bile *bile; + struct board_fidonet_msgid_id_map_entry *fidonet_msgid_map; + size_t nfidonet_msgid_map_entries; }; extern const struct struct_field board_fields[]; @@ -50,6 +65,12 @@ struct board_post { char *body; unsigned long parent_post_id; char via[10]; + char fidonet_reply[32]; + char fidonet_from[32]; + char fidonet_to[32]; + char fidonet_origin[72]; + char fidonet_msgid_orig[40]; + struct board_post_fidonet_msgid fidonet_msgid; }; extern const struct bile_object_field board_post_object_fields[]; extern const size_t nboard_post_object_fields; @@ -67,5 +88,9 @@ extern const struct bile_object_field board_thread_obj extern const size_t nboard_thread_object_fields; void board_show(struct session *s, short id); +short board_post_create(struct board *board, struct board_thread *thread, + struct board_post *post); +void board_delete_post(struct session *s, struct board *board, + struct board_post *post, struct board_thread *thread); #endif --- db.c Thu Feb 23 17:07:31 2023 +++ db.c Sat Feb 25 17:21:42 2023 @@ -366,6 +366,9 @@ db_migrate(struct db *tdb, short is_new, Str255 fullpa /* per-version migrations */ while (ver < DB_CUR_VERS) { + progress("Migrating from version %d to %d...", (short)ver, + (short)(ver + 1)); + switch (ver) { case 1: { /* 1->2, added user is_enabled field */ @@ -599,7 +602,8 @@ db_migrate(struct db *tdb, short is_new, Str255 fullpa bile_error(NULL)); for (n = 0; (o = bile_get_nth_of_type(tdb->bile, n, - MAIL_SPOOL_MESSAGE_RTYPE)); n++) { + MAIL_SPOOL_MESSAGE_RTYPE)); n++) { + progress("Copying mail message %ld...", o->id); size = bile_read_alloc(tdb->bile, o->type, o->id, &data); bile_write(mail_bile, o->type, o->id, data, size); @@ -615,6 +619,7 @@ db_migrate(struct db *tdb, short is_new, Str255 fullpa MAIL_SPOOL_MESSAGE_RTYPE))) { id = o->id; xfree(&o); + progress("Deleting old mail message %ld...", id); bile_delete(tdb->bile, MAIL_SPOOL_MESSAGE_RTYPE, id, 0); } bile_write_map(tdb->bile); @@ -622,10 +627,62 @@ db_migrate(struct db *tdb, short is_new, Str255 fullpa break; } + case 14: { + /* 14->15, boards and posts get fido fields */ + struct bile_object *o; + struct board *board; + size_t nids, grow, size, n, j; + unsigned long *ids; + + grow = member_size(struct board, fidonet_area); + + nids = bile_sorted_ids_by_type(tdb->bile, DB_BOARD_RTYPE, &ids); + for (n = 0; n < nids; n++) { + o = bile_find(tdb->bile, DB_BOARD_RTYPE, ids[n]); + progress("Growing board %ld/%ld...", n + 1, nids); + size = o->size + grow; + if (bile_resize(tdb->bile, o->type, o->id, size) != size) + panic("failed resizing board %ld", o->id); + xfree(&o); + } + xfree(&ids); + + db_cache_boards(tdb); + + grow = member_size(struct board_post, fidonet_reply) + + member_size(struct board_post, fidonet_from) + + member_size(struct board_post, fidonet_to) + + member_size(struct board_post, fidonet_origin) + + member_size(struct board_post, fidonet_msgid_orig) + + member_size(struct board_post, fidonet_msgid); + + for (n = 0; n < tdb->nboards; n++) { + board = &tdb->boards[n]; + nids = bile_sorted_ids_by_type(board->bile, + BOARD_POST_RTYPE, &ids); + if (!nids) + continue; + for (j = 0; j < nids; j++) { + o = bile_find(board->bile, BOARD_POST_RTYPE, ids[j]); + progress("Growing board %ld post %ld/%ld...", + n + 1, j + 1, nids); + size = o->size + grow; + if (bile_resize(board->bile, o->type, o->id, + size) != size) + panic("failed resizing board %ld post %ld", + board->id, o->id); + xfree(&o); + } + xfree(&ids); + } + break; } + } ver++; } + + progress(NULL); /* store new version */ ver = DB_CUR_VERS; @@ -676,6 +733,8 @@ db_cache_boards(struct db *tdb) for (n = 0; n < tdb->nboards; n++) { if (tdb->boards[n].bile) bile_close(tdb->boards[n].bile); + if (tdb->boards[n].fidonet_msgid_map != NULL) + xfree(&tdb->boards[n].fidonet_msgid_map); } xfree(&tdb->boards); } @@ -736,7 +795,7 @@ db_cache_boards(struct db *tdb) if (ask("Failed to open board bile %s (error %d), recreate it?", board_filename, bile_error(NULL)) == false) - exit(0); + panic("Can't open board file, exiting"); tdb->boards[n].bile = db_board_create(tdb, &tdb->boards[n], true); if (tdb->boards[n].bile == NULL) @@ -785,6 +844,17 @@ db_board_create(struct db *tdb, struct board *board, b PtoCstr(board_filename), bile_error(NULL)); return board_bile; +} + +void +db_board_delete(struct db *tdb, struct board *board) +{ + if (bile_delete(tdb->bile, DB_BOARD_RTYPE, board->id, 0) != 0) { + warn("deletion of board %ld failed: %d", board->id, + bile_error(tdb->bile)); + return; + } + bile_close(board->bile); } void --- db.h Thu Feb 23 16:34:03 2023 +++ db.h Sat Feb 25 16:52:58 2023 @@ -19,12 +19,11 @@ #include <time.h> -#define SUBTEXT_CREATOR 'SUBT' +#define DB_CUR_VERS 15 +#define SUBTEXT_CREATOR 'SUBT' #define DB_TYPE 'STDB' -#define DB_CUR_VERS 14 - #define DB_TRUE 0x100 #define DB_FALSE 0x000 @@ -54,6 +53,7 @@ #define BOARD_FILENAME_EXT "brd" #define BOARD_THREAD_RTYPE 'BDTH' #define BOARD_POST_RTYPE 'BDPS' +#define BOARD_FIDONET_MSGID_CACHE_RTYPE 'BDFC' #define FOLDER_FILENAME_EXT "fld" #define FOLDER_FILE_RTYPE 'FILE' @@ -117,6 +117,7 @@ void db_config_save(struct db *tdb); void db_cache_boards(struct db *tdb); struct bile * db_board_create(struct db *tdb, struct board *board, bool delete_first); +void db_board_delete(struct db *tdb, struct board *board); void db_cache_folders(struct db *tdb); struct bile * db_folder_create(struct db *tdb, struct folder *folder, bool delete_first); --- fidopkt.c Fri Feb 24 14:11:23 2023 +++ fidopkt.c Sat Feb 25 15:28:56 2023 @@ -114,27 +114,27 @@ fidopkt_read_until(char **buf, size_t *buf_len, char d bool fidopkt_parse_msgid(struct fidopkt *pkt) { + static char garbage[50]; unsigned short zone, net, node, point = 0; - char garbage[member_size(struct fidopkt, msgid_orig) + 1]; unsigned long id; /* 37246.fsxnet_fsx_gen@21:1/137.1 28583dba */ - if (sscanf(pkt->msgid_orig, "%[^@]@%d:%d/%d.%d %lx", + if (sscanf(pkt->msgid_orig, "%49[^@]@%d:%d/%d.%d %lx", &garbage, &zone, &net, &node, &point, &id) == 6) goto found; /* 37246.fsxnet_fsx_gen@21:1/137 28583dba */ - if (sscanf(pkt->msgid_orig, "%[^@]@%d:%d/%d %lx", + if (sscanf(pkt->msgid_orig, "%49[^@]@%d:%d/%d %lx", &garbage, &zone, &net, &node, &id) == 5) goto found; /* 21:3/110.10@fsxnet 05996db9 */ - if (sscanf(pkt->msgid_orig, "%d:%d/%d.%d@%s %lx", + if (sscanf(pkt->msgid_orig, "%d:%d/%d.%d@%49s %lx", &zone, &net, &node, &point, &garbage, &id) == 6) goto found; /* 21:3/110@fsxnet 05996db9 */ - if (sscanf(pkt->msgid_orig, "%d:%d/%d@%s %lx", + if (sscanf(pkt->msgid_orig, "%d:%d/%d@%49s %lx", &zone, &net, &node, &garbage, &id) == 5) goto found; @@ -160,7 +160,8 @@ found: #ifdef FIDOPKT_DEBUG logger_printf("[fidopkt] %s -> zone:%d net:%d node:%d point:%d id:%lu", - pkt->msgid_orig, zone, net, node, point, id); + pkt->msgid_orig, pkt->msgid_zone, pkt->msgid_net, pkt->msgid_node, + pkt->msgid_point, pkt->msgid); #endif return true; } @@ -305,8 +306,7 @@ fidopkt_parse(char *packet_filename, char *buf, size_t #ifdef FIDOPKT_DEBUG strlcpy(tz, line + 1 + 7, sizeof(tz)); #endif - } - else if (strncmp(line + 1, "MSGID: ", 7) == 0) { + } else if (strncmp(line + 1, "MSGID: ", 7) == 0) { /* * FTS-0009.001 says: ^AMSGID: origaddr serialno * serialno is an 8 char hexadecimal string unique to the @@ -330,7 +330,7 @@ fidopkt_parse(char *packet_filename, char *buf, size_t memcpy(ret->message + message_len, line, llen - 1); message_len += llen - 1; ret->message[message_len++] = '\r'; - //ret->message[message_len++] = '\n'; + ret->message[message_len++] = '\n'; } else { /* long line */ memcpy(ret->message + message_len, line, llen); @@ -377,7 +377,7 @@ fidopkt_parse(char *packet_filename, char *buf, size_t lastbreak = ret->message; for (n = 0; n <= ret->message_len; n++) { - if (ret->message[n] == '\r' || n == ret->message_len) { + if (ret->message[n] == '\n' || n == ret->message_len) { was = ret->message[n]; ret->message[n] = '\0'; logger_printf("[fidopkt] %s", lastbreak); --- fidopkt.h Fri Feb 24 12:50:46 2023 +++ fidopkt.h Fri Feb 24 16:08:12 2023 @@ -29,10 +29,10 @@ struct fidopkt { char reply[32]; char msgid_orig[32]; unsigned long msgid; - u_int16_t msgid_zone; - u_int16_t msgid_net; - u_int16_t msgid_node; - u_int16_t msgid_point; + unsigned short msgid_zone; + unsigned short msgid_net; + unsigned short msgid_node; + unsigned short msgid_point; char *message; size_t message_len; }; --- folder.h Thu Feb 23 20:48:02 2023 +++ folder.h Fri Feb 24 17:24:27 2023 @@ -20,6 +20,7 @@ #include <stddef.h> #include <stdio.h> #include "db.h" +#include "settings.h" #include "sha1.h" struct folder { --- zip.h Tue Feb 21 17:44:22 2023 +++ zip.h Fri Feb 24 09:52:52 2023 @@ -30,8 +30,8 @@ (((unsigned char *)buf)[0])) typedef bool zip_extract_decider(char *filename, size_t extracted_size); -typedef void zip_extract_processor(char *filename, size_t extracted_size, - unsigned char *extracted_data); +typedef void zip_extract_processor(char *filename, + size_t extracted_size, unsigned char *extracted_data); bool zip_read_file(Str255 path, zip_extract_decider *decider, zip_extract_processor *processor);