@@ -82,6 +82,7 @@ static unsigned long file_rotate_count;
8282static unsigned long file_rotate_size ;
8383static str file_suffix ;
8484static pv_elem_p file_suffix_format ;
85+ static str escape_delimiter = {0 , 0 };
8586
8687static void raise_rotation_event (struct flat_file * file , const char * reason );
8788static void update_counters_and_rotate (struct flat_file * file ,
@@ -114,6 +115,7 @@ static const param_export_t mod_params[] = {
114115 {"rotate_count" , INT_PARAM |STR_PARAM |USE_FUNC_PARAM , (void * )rotate_count_param },
115116 {"rotate_size" , INT_PARAM |STR_PARAM |USE_FUNC_PARAM , (void * )rotate_size_param },
116117 {"suffix" , STR_PARAM , & file_suffix .s },
118+ {"escape_delimiter" , STR_PARAM , & escape_delimiter .s },
117119 {0 ,0 ,0 }
118120};
119121
@@ -281,6 +283,17 @@ static int mod_init(void) {
281283 LM_DBG ("The delimiter for separating columns in files was set at %.*s\n" , delimiter .len , delimiter .s );
282284 }
283285
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+
284297 if (initial_capacity <= 0 || initial_capacity > 65535 ) {
285298 LM_WARN ("bad value for maximum open sockets (%d)\n" , initial_capacity );
286299 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,
878891 }
879892 }
880893
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+ }
881915 io_param [idx ].iov_base = param -> val .s .s ;
882916 io_param [idx ].iov_len = param -> val .s .len ;
883917 idx ++ ;
0 commit comments