factor copy_msg_convert() out to own source file
This commit is contained in:
		
							parent
							
								
									46d244533e
								
							
						
					
					
						commit
						a32964c34e
					
				
					 4 changed files with 191 additions and 181 deletions
				
			
		|  | @ -7,7 +7,7 @@ mbsync_SOURCES = \ | ||||||
| 	driver.c drv_proxy.c \ | 	driver.c drv_proxy.c \ | ||||||
| 	drv_imap.c imap_msgs.c \ | 	drv_imap.c imap_msgs.c \ | ||||||
| 	drv_maildir.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 | 	main.c main_sync.c main_list.c | ||||||
| noinst_HEADERS = \ | noinst_HEADERS = \ | ||||||
| 	common.h config.h socket.h \ | 	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 msg_fetched( int sts, void *aux ); | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
|  | @ -103,177 +94,6 @@ copy_msg( copy_vars_t *vars ) | ||||||
| 
 | 
 | ||||||
| static void msg_stored( int sts, uint uid, void *aux ); | 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 | static void | ||||||
| msg_fetched( int sts, void *aux ) | 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 ); | 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 ); | 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…
	
	Add table
		
		Reference in a new issue