@@ -82,6 +82,7 @@ static unsigned long file_rotate_count;
82
82
static unsigned long file_rotate_size ;
83
83
static str file_suffix ;
84
84
static pv_elem_p file_suffix_format ;
85
+ static str escape_delimiter = {0 , 0 };
85
86
86
87
static void raise_rotation_event (struct flat_file * file , const char * reason );
87
88
static void update_counters_and_rotate (struct flat_file * file ,
@@ -114,6 +115,7 @@ static const param_export_t mod_params[] = {
114
115
{"rotate_count" , INT_PARAM |STR_PARAM |USE_FUNC_PARAM , (void * )rotate_count_param },
115
116
{"rotate_size" , INT_PARAM |STR_PARAM |USE_FUNC_PARAM , (void * )rotate_size_param },
116
117
{"suffix" , STR_PARAM , & file_suffix .s },
118
+ {"escape_delimiter" , STR_PARAM , & escape_delimiter .s },
117
119
{0 ,0 ,0 }
118
120
};
119
121
@@ -281,6 +283,17 @@ static int mod_init(void) {
281
283
LM_DBG ("The delimiter for separating columns in files was set at %.*s\n" , delimiter .len , delimiter .s );
282
284
}
283
285
286
+ if (escape_delimiter .s ) {
287
+ escape_delimiter .len = strlen (escape_delimiter .s );
288
+ if (escape_delimiter .len != delimiter .len ) {
289
+ LM_ERR ("\"escape_delimiter\" length (%d) must match \"delimiter\" length (%d)\n" ,
290
+ escape_delimiter .len , delimiter .len );
291
+ return -1 ;
292
+ }
293
+ LM_DBG ("Delimiter escaping enabled: \"%.*s\" → \"%.*s\"\n" ,
294
+ delimiter .len , delimiter .s , escape_delimiter .len , escape_delimiter .s );
295
+ }
296
+
284
297
if (initial_capacity <= 0 || initial_capacity > 65535 ) {
285
298
LM_WARN ("bad value for maximum open sockets (%d)\n" , initial_capacity );
286
299
initial_capacity = FLAT_DEFAULT_MAX_FD ;
@@ -878,6 +891,27 @@ static int flat_raise(struct sip_msg *msg, str* ev_name, evi_reply_sock *sock,
878
891
}
879
892
}
880
893
894
+ /* if escape_delimiter is configured, replace any in-value
895
+ * occurrences of the delimiter with the escape sequence */
896
+ if (escape_delimiter .s ) {
897
+ if (delimiter .len == 1 ) { /* fast single-char */
898
+ for (i = 0 ; i < param -> val .s .len ; i ++ )
899
+ if (param -> val .s .s [i ] == delimiter .s [0 ])
900
+ param -> val .s .s [i ] = escape_delimiter .s [0 ];
901
+ } else { /* multi-char delim */
902
+ char * p = param -> val .s .s ;
903
+ char * end = p + param -> val .s .len - delimiter .len ;
904
+ while (p <= end ) {
905
+ if (memcmp (p , delimiter .s , delimiter .len ) == 0 ) {
906
+ memcpy (p , escape_delimiter .s , delimiter .len );
907
+ p += delimiter .len ;
908
+ end = param -> val .s .s + param -> val .s .len - delimiter .len ;
909
+ } else {
910
+ p ++ ;
911
+ }
912
+ }
913
+ }
914
+ }
881
915
io_param [idx ].iov_base = param -> val .s .s ;
882
916
io_param [idx ].iov_len = param -> val .s .len ;
883
917
idx ++ ;
0 commit comments