commit a32964c34eef2a3f11dcbd7eb37a4b545ebce1d5
parent 46d244533e13af878301d0dfd4ed8fb5e911696d
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date: Sun, 1 May 2022 14:16:28 +0200
factor copy_msg_convert() out to own source file
Diffstat:
4 files changed, 191 insertions(+), 181 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
@@ -7,7 +7,7 @@ mbsync_SOURCES = \
driver.c drv_proxy.c \
drv_imap.c imap_msgs.c \
drv_maildir.c \
- sync.c sync_state.c \
+ sync.c sync_state.c sync_msg_cvt.c \
main.c main_sync.c main_list.c
noinst_HEADERS = \
common.h config.h socket.h \
diff --git a/src/sync.c b/src/sync.c
@@ -79,15 +79,6 @@ sanitize_flags( uchar tflags, sync_vars_t *svars, int t )
}
-typedef struct copy_vars {
- void (*cb)( int sts, uint uid, struct copy_vars *vars );
- void *aux;
- sync_rec_t *srec; /* also ->tuid */
- message_t *msg;
- msg_data_t data;
- int minimal;
-} copy_vars_t;
-
static void msg_fetched( int sts, void *aux );
static void
@@ -104,177 +95,6 @@ copy_msg( copy_vars_t *vars )
static void msg_stored( int sts, uint uid, void *aux );
static void
-copy_msg_bytes( char **out_ptr, const char *in_buf, uint *in_idx, uint in_len, int in_cr, int out_cr )
-{
- char *out = *out_ptr;
- uint idx = *in_idx;
- if (out_cr != in_cr) {
- char c;
- if (out_cr) {
- for (; idx < in_len; idx++) {
- if ((c = in_buf[idx]) != '\r') {
- if (c == '\n')
- *out++ = '\r';
- *out++ = c;
- }
- }
- } else {
- for (; idx < in_len; idx++) {
- if ((c = in_buf[idx]) != '\r')
- *out++ = c;
- }
- }
- } else {
- memcpy( out, in_buf + idx, in_len - idx );
- out += in_len - idx;
- idx = in_len;
- }
- *out_ptr = out;
- *in_idx = idx;
-}
-
-static char *
-copy_msg_convert( int in_cr, int out_cr, copy_vars_t *vars )
-{
- char *in_buf = vars->data.data;
- uint in_len = vars->data.len;
- uint idx = 0, sbreak = 0, ebreak = 0, break2 = UINT_MAX;
- uint lines = 0, hdr_crs = 0, bdy_crs = 0, app_cr = 0, extra = 0;
- uint add_subj = 0;
-
- if (vars->srec) {
- nloop: ;
- uint start = idx;
- uint line_crs = 0;
- while (idx < in_len) {
- char c = in_buf[idx++];
- if (c == '\r') {
- line_crs++;
- } else if (c == '\n') {
- if (!ebreak && starts_with_upper( in_buf + start, (int)(in_len - start), "X-TUID: ", 8 )) {
- extra = (sbreak = start) - (ebreak = idx);
- if (!vars->minimal)
- goto oke;
- } else {
- if (break2 == UINT_MAX && vars->minimal &&
- starts_with_upper( in_buf + start, (int)(in_len - start), "SUBJECT:", 8 )) {
- break2 = start + 8;
- if (break2 < in_len && in_buf[break2] == ' ')
- break2++;
- }
- lines++;
- hdr_crs += line_crs;
- }
- if (idx - line_crs - 1 == start) {
- if (!ebreak)
- sbreak = ebreak = start;
- if (vars->minimal) {
- in_len = idx;
- if (break2 == UINT_MAX) {
- break2 = start;
- add_subj = 1;
- }
- }
- goto oke;
- }
- goto nloop;
- }
- }
- free( in_buf );
- return "has incomplete header";
- oke:
- app_cr = out_cr && (!in_cr || hdr_crs);
- extra += 8 + TUIDL + app_cr + 1;
- }
- if (out_cr != in_cr) {
- for (; idx < in_len; idx++) {
- char c = in_buf[idx];
- if (c == '\r')
- bdy_crs++;
- else if (c == '\n')
- lines++;
- }
- extra -= hdr_crs + bdy_crs;
- if (out_cr)
- extra += lines;
- }
-
- uint dummy_msg_len = 0;
- char dummy_msg_buf[256];
- static const char dummy_pfx[] = "[placeholder] ";
- static const char dummy_subj[] = "Subject: [placeholder] (No Subject)";
- static const char dummy_msg[] =
- "Having a size of %s, this message is over the MaxSize limit.%s"
- "Flag it and sync again (Sync mode Upgrade) to fetch its real contents.%s";
- static const char dummy_flag[] =
- "%s"
- "The original message is flagged as important.%s";
-
- if (vars->minimal) {
- char sz[32];
-
- if (vars->msg->size < 1024000)
- sprintf( sz, "%dKiB", (int)(vars->msg->size >> 10) );
- else
- sprintf( sz, "%.1fMiB", vars->msg->size / 1048576. );
- const char *nl = app_cr ? "\r\n" : "\n";
- dummy_msg_len = (uint)sprintf( dummy_msg_buf, dummy_msg, sz, nl, nl );
- if (vars->data.flags & F_FLAGGED) {
- vars->data.flags &= ~F_FLAGGED;
- dummy_msg_len += (uint)sprintf( dummy_msg_buf + dummy_msg_len, dummy_flag, nl, nl );
- }
- extra += dummy_msg_len;
- extra += add_subj ? strlen(dummy_subj) + app_cr + 1 : strlen(dummy_pfx);
- }
-
- vars->data.len = in_len + extra;
- if (vars->data.len > INT_MAX) {
- free( in_buf );
- return "is too big after conversion";
- }
- char *out_buf = vars->data.data = nfmalloc( vars->data.len );
- idx = 0;
- if (vars->srec) {
- if (break2 < sbreak) {
- copy_msg_bytes( &out_buf, in_buf, &idx, break2, in_cr, out_cr );
- memcpy( out_buf, dummy_pfx, strlen(dummy_pfx) );
- out_buf += strlen(dummy_pfx);
- }
- copy_msg_bytes( &out_buf, in_buf, &idx, sbreak, in_cr, out_cr );
-
- memcpy( out_buf, "X-TUID: ", 8 );
- out_buf += 8;
- memcpy( out_buf, vars->srec->tuid, TUIDL );
- out_buf += TUIDL;
- if (app_cr)
- *out_buf++ = '\r';
- *out_buf++ = '\n';
- idx = ebreak;
-
- if (break2 != UINT_MAX && break2 >= sbreak) {
- copy_msg_bytes( &out_buf, in_buf, &idx, break2, in_cr, out_cr );
- if (!add_subj) {
- memcpy( out_buf, dummy_pfx, strlen(dummy_pfx) );
- out_buf += strlen(dummy_pfx);
- } else {
- memcpy( out_buf, dummy_subj, strlen(dummy_subj) );
- out_buf += strlen(dummy_subj);
- if (app_cr)
- *out_buf++ = '\r';
- *out_buf++ = '\n';
- }
- }
- }
- copy_msg_bytes( &out_buf, in_buf, &idx, in_len, in_cr, out_cr );
-
- if (vars->minimal)
- memcpy( out_buf, dummy_msg_buf, dummy_msg_len );
-
- free( in_buf );
- return NULL;
-}
-
-static void
msg_fetched( int sts, void *aux )
{
copy_vars_t *vars = (copy_vars_t *)aux;
diff --git a/src/sync_msg_cvt.c b/src/sync_msg_cvt.c
@@ -0,0 +1,179 @@
+// SPDX-FileCopyrightText: 2000-2002 Michael R. Elkins <me@mutt.org>
+// SPDX-FileCopyrightText: 2002-2022 Oswald Buddenhagen <ossi@users.sf.net>
+// SPDX-License-Identifier: GPL-2.0-or-later WITH LicenseRef-isync-GPL-exception
+//
+// mbsync - mailbox synchronizer
+//
+
+#include "sync_p.h"
+
+static void
+copy_msg_bytes( char **out_ptr, const char *in_buf, uint *in_idx, uint in_len, int in_cr, int out_cr )
+{
+ char *out = *out_ptr;
+ uint idx = *in_idx;
+ if (out_cr != in_cr) {
+ char c;
+ if (out_cr) {
+ for (; idx < in_len; idx++) {
+ if ((c = in_buf[idx]) != '\r') {
+ if (c == '\n')
+ *out++ = '\r';
+ *out++ = c;
+ }
+ }
+ } else {
+ for (; idx < in_len; idx++) {
+ if ((c = in_buf[idx]) != '\r')
+ *out++ = c;
+ }
+ }
+ } else {
+ memcpy( out, in_buf + idx, in_len - idx );
+ out += in_len - idx;
+ idx = in_len;
+ }
+ *out_ptr = out;
+ *in_idx = idx;
+}
+
+char *
+copy_msg_convert( int in_cr, int out_cr, copy_vars_t *vars )
+{
+ char *in_buf = vars->data.data;
+ uint in_len = vars->data.len;
+ uint idx = 0, sbreak = 0, ebreak = 0, break2 = UINT_MAX;
+ uint lines = 0, hdr_crs = 0, bdy_crs = 0, app_cr = 0, extra = 0;
+ uint add_subj = 0;
+
+ if (vars->srec) {
+ nloop: ;
+ uint start = idx;
+ uint line_crs = 0;
+ while (idx < in_len) {
+ char c = in_buf[idx++];
+ if (c == '\r') {
+ line_crs++;
+ } else if (c == '\n') {
+ if (!ebreak && starts_with_upper( in_buf + start, (int)(in_len - start), "X-TUID: ", 8 )) {
+ extra = (sbreak = start) - (ebreak = idx);
+ if (!vars->minimal)
+ goto oke;
+ } else {
+ if (break2 == UINT_MAX && vars->minimal &&
+ starts_with_upper( in_buf + start, (int)(in_len - start), "SUBJECT:", 8 )) {
+ break2 = start + 8;
+ if (break2 < in_len && in_buf[break2] == ' ')
+ break2++;
+ }
+ lines++;
+ hdr_crs += line_crs;
+ }
+ if (idx - line_crs - 1 == start) {
+ if (!ebreak)
+ sbreak = ebreak = start;
+ if (vars->minimal) {
+ in_len = idx;
+ if (break2 == UINT_MAX) {
+ break2 = start;
+ add_subj = 1;
+ }
+ }
+ goto oke;
+ }
+ goto nloop;
+ }
+ }
+ free( in_buf );
+ return "has incomplete header";
+ oke:
+ app_cr = out_cr && (!in_cr || hdr_crs);
+ extra += 8 + TUIDL + app_cr + 1;
+ }
+ if (out_cr != in_cr) {
+ for (; idx < in_len; idx++) {
+ char c = in_buf[idx];
+ if (c == '\r')
+ bdy_crs++;
+ else if (c == '\n')
+ lines++;
+ }
+ extra -= hdr_crs + bdy_crs;
+ if (out_cr)
+ extra += lines;
+ }
+
+ uint dummy_msg_len = 0;
+ char dummy_msg_buf[256];
+ static const char dummy_pfx[] = "[placeholder] ";
+ static const char dummy_subj[] = "Subject: [placeholder] (No Subject)";
+ static const char dummy_msg[] =
+ "Having a size of %s, this message is over the MaxSize limit.%s"
+ "Flag it and sync again (Sync mode Upgrade) to fetch its real contents.%s";
+ static const char dummy_flag[] =
+ "%s"
+ "The original message is flagged as important.%s";
+
+ if (vars->minimal) {
+ char sz[32];
+
+ if (vars->msg->size < 1024000)
+ sprintf( sz, "%dKiB", (int)(vars->msg->size >> 10) );
+ else
+ sprintf( sz, "%.1fMiB", vars->msg->size / 1048576. );
+ const char *nl = app_cr ? "\r\n" : "\n";
+ dummy_msg_len = (uint)sprintf( dummy_msg_buf, dummy_msg, sz, nl, nl );
+ if (vars->data.flags & F_FLAGGED) {
+ vars->data.flags &= ~F_FLAGGED;
+ dummy_msg_len += (uint)sprintf( dummy_msg_buf + dummy_msg_len, dummy_flag, nl, nl );
+ }
+ extra += dummy_msg_len;
+ extra += add_subj ? strlen(dummy_subj) + app_cr + 1 : strlen(dummy_pfx);
+ }
+
+ vars->data.len = in_len + extra;
+ if (vars->data.len > INT_MAX) {
+ free( in_buf );
+ return "is too big after conversion";
+ }
+ char *out_buf = vars->data.data = nfmalloc( vars->data.len );
+ idx = 0;
+ if (vars->srec) {
+ if (break2 < sbreak) {
+ copy_msg_bytes( &out_buf, in_buf, &idx, break2, in_cr, out_cr );
+ memcpy( out_buf, dummy_pfx, strlen(dummy_pfx) );
+ out_buf += strlen(dummy_pfx);
+ }
+ copy_msg_bytes( &out_buf, in_buf, &idx, sbreak, in_cr, out_cr );
+
+ memcpy( out_buf, "X-TUID: ", 8 );
+ out_buf += 8;
+ memcpy( out_buf, vars->srec->tuid, TUIDL );
+ out_buf += TUIDL;
+ if (app_cr)
+ *out_buf++ = '\r';
+ *out_buf++ = '\n';
+ idx = ebreak;
+
+ if (break2 != UINT_MAX && break2 >= sbreak) {
+ copy_msg_bytes( &out_buf, in_buf, &idx, break2, in_cr, out_cr );
+ if (!add_subj) {
+ memcpy( out_buf, dummy_pfx, strlen(dummy_pfx) );
+ out_buf += strlen(dummy_pfx);
+ } else {
+ memcpy( out_buf, dummy_subj, strlen(dummy_subj) );
+ out_buf += strlen(dummy_subj);
+ if (app_cr)
+ *out_buf++ = '\r';
+ *out_buf++ = '\n';
+ }
+ }
+ }
+ copy_msg_bytes( &out_buf, in_buf, &idx, in_len, in_cr, out_cr );
+
+ if (vars->minimal)
+ memcpy( out_buf, dummy_msg_buf, dummy_msg_len );
+
+ free( in_buf );
+ return NULL;
+}
diff --git a/src/sync_p.h b/src/sync_p.h
@@ -103,3 +103,14 @@ void assign_tuid( sync_vars_t *svars, sync_rec_t *srec );
int match_tuids( sync_vars_t *svars, int t, message_t *msgs );
sync_rec_t *upgrade_srec( sync_vars_t *svars, sync_rec_t *srec, int t );
+
+typedef struct copy_vars {
+ void (*cb)( int sts, uint uid, struct copy_vars *vars );
+ void *aux;
+ sync_rec_t *srec; /* also ->tuid */
+ message_t *msg;
+ msg_data_t data;
+ int minimal;
+} copy_vars_t;
+
+char *copy_msg_convert( int in_cr, int out_cr, copy_vars_t *vars );