factor copy_msg_convert() out to own source file
This commit is contained in:
parent
46d244533e
commit
a32964c34e
|
@ -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 \
|
||||
|
|
180
src/sync.c
180
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
|
||||
|
@ -103,177 +94,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 )
|
||||
{
|
||||
|
|
179
src/sync_msg_cvt.c
Normal file
179
src/sync_msg_cvt.c
Normal file
|
@ -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;
|
||||
}
|
11
src/sync_p.h
11
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 );
|
||||
|
|
Loading…
Reference in New Issue
Block a user