mirror of https://git.code.sf.net/p/isync/isync
Oswald Buddenhagen
3 years ago
4 changed files with 191 additions and 181 deletions
@ -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; |
||||
} |
Loading…
Reference in new issue