talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

utils.h (13687B)


      1 /*
      2  * Claws Mail -- a GTK based, lightweight, and fast e-mail client
      3  * Copyright (C) 1999-2024 The Claws Mail Team and Hiroyuki Yamamoto
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License as published by
      7  * the Free Software Foundation; either version 3 of the License, or
      8  * (at your option) any later version.
      9  *
     10  * This program is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  * GNU General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU General Public License
     16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
     17  *
     18  * The code of the g_utf8_substring function below is owned by
     19  * Matthias Clasen <matthiasc@src.gnome.org>/<mclasen@redhat.com>
     20  * and is got from GLIB 2.30
     21  */
     22 
     23 #ifndef __UTILS_H__
     24 #define __UTILS_H__
     25 
     26 #include <glib.h>
     27 #include <glib-object.h>
     28 #include <stdio.h>
     29 #include <string.h>
     30 #include <stdlib.h>
     31 #include <unistd.h>
     32 #include <sys/types.h>
     33 #include <time.h>
     34 #if HAVE_ALLOCA_H
     35 #  include <alloca.h>
     36 #endif
     37 #include <wchar.h>
     38 
     39 /* Handling Base64 content in procmime and prefs_customheader */
     40 #define B64_LINE_SIZE 57
     41 
     42 /* Wrappers for C library function that take pathname arguments. */
     43 #  include <glib/gstdio.h>
     44 
     45 /* why is this sometimes undefined !? */
     46 #ifndef G_MAXOFFSET
     47 typedef gint64 goffset;
     48 #define G_MINOFFSET	G_MININT64
     49 #define G_MAXOFFSET	G_MAXINT64
     50 #endif
     51 
     52 #ifndef BIG_ENDIAN_HOST
     53   #if (G_BYTE_ORDER == G_BIG_ENDIAN)
     54     #define BIG_ENDIAN_HOST 1
     55   #endif
     56 #endif
     57 
     58 #define CHDIR_RETURN_IF_FAIL(dir) \
     59 { \
     60 	if (change_dir(dir) < 0) return; \
     61 }
     62 
     63 #define CHDIR_RETURN_VAL_IF_FAIL(dir, val) \
     64 { \
     65 	if (change_dir(dir) < 0) return val; \
     66 }
     67 
     68 #define CHDIR_EXEC_CODE_RETURN_VAL_IF_FAIL(dir, val, code) \
     69 { \
     70 	if (change_dir(dir) < 0) { \
     71 		code \
     72 		return val; \
     73 	} \
     74 }
     75 
     76 #define MAX_ALLOCA_MEM_SIZE 102400
     77 
     78 #define Xalloca(ptr, size, iffail) \
     79 { \
     80 	size_t __size = size; \
     81  \
     82 	if (__size > MAX_ALLOCA_MEM_SIZE) { \
     83 		g_warning("%" G_GSIZE_FORMAT " bytes exceeds max alloca size '%d'", __size, MAX_ALLOCA_MEM_SIZE); \
     84 		iffail; \
     85 	} \
     86 	if ((ptr = alloca(__size)) == NULL) { \
     87 		g_warning("can't allocate memory"); \
     88 		iffail; \
     89 	} \
     90 }
     91 
     92 #define Xstrdup_a(ptr, str, iffail) \
     93 { \
     94 	gchar *__tmp; \
     95 	size_t __size = strlen(str); \
     96  \
     97 	if (__size > MAX_ALLOCA_MEM_SIZE) { \
     98 		g_warning("%" G_GSIZE_FORMAT " bytes exceeds max alloca size '%d'", __size, MAX_ALLOCA_MEM_SIZE); \
     99 		iffail; \
    100 	} \
    101 	if ((__tmp = alloca(__size + 1)) == NULL) { \
    102 		g_warning("can't allocate memory"); \
    103 		iffail; \
    104 	} else \
    105 		strcpy(__tmp, str); \
    106  \
    107 	ptr = __tmp; \
    108 }
    109 
    110 #define Xstrndup_a(ptr, str, len, iffail) \
    111 { \
    112 	gchar *__tmp; \
    113 	size_t __size = len; \
    114  \
    115 	if (__size > MAX_ALLOCA_MEM_SIZE) { \
    116 		g_warning("%" G_GSIZE_FORMAT "bytes exceeds max alloca size '%d'", __size, MAX_ALLOCA_MEM_SIZE); \
    117 		iffail; \
    118 	} \
    119 	if ((__tmp = alloca(__size + 1)) == NULL) { \
    120 		g_warning("can't allocate memory"); \
    121 		iffail; \
    122 	} else { \
    123 		memcpy(__tmp, str, __size); \
    124 		__tmp[__size] = '\0'; \
    125 	} \
    126  \
    127 	ptr = __tmp; \
    128 }
    129 
    130 #define Xstrcat_a(ptr, str1, str2, iffail) \
    131 { \
    132 	gchar *__tmp; \
    133 	size_t len1, len2; \
    134  \
    135 	len1 = strlen(str1); \
    136 	len2 = strlen(str2); \
    137 	if (len1 + len2 > MAX_ALLOCA_MEM_SIZE) { \
    138 		g_warning("%" G_GSIZE_FORMAT " bytes exceeds max alloca size '%d'", len1 + len2, MAX_ALLOCA_MEM_SIZE); \
    139 		iffail; \
    140 	} \
    141 	if ((__tmp = alloca(len1 + len2 + 1)) == NULL) { \
    142 		g_warning("can't allocate memory"); \
    143 		iffail; \
    144 	} else { \
    145 		memcpy(__tmp, str1, len1); \
    146 		memcpy(__tmp + len1, str2, len2 + 1); \
    147 	} \
    148  \
    149 	ptr = __tmp; \
    150 }
    151 
    152 #define AUTORELEASE_STR(str, iffail) \
    153 { \
    154 	gchar *__str; \
    155 	Xstrdup_a(__str, str, iffail); \
    156 	g_free(str); \
    157 	str = __str; \
    158 }
    159 
    160 #define FILE_OP_ERROR(file, func) \
    161 { \
    162 	g_printerr("%s: ", file); \
    163 	fflush(stderr); \
    164 	perror(func); \
    165 }
    166 
    167 #define IS_ASCII(c) (((guchar) c) <= 0177 ? 1 : 0)
    168 
    169 #define cm_return_val_if_fail(expr,val) G_STMT_START {			\
    170 	if (!(expr)) {							\
    171 		g_print("%s:%d Condition %s failed\n", __FILE__, __LINE__, #expr);\
    172 		return val;						\
    173 	} 								\
    174 } G_STMT_END
    175 
    176 #define cm_return_if_fail(expr) G_STMT_START {				\
    177 	if (!(expr)) {							\
    178 		g_print("%s:%d Condition %s failed\n", __FILE__, __LINE__, #expr);\
    179 		return;							\
    180 	} 								\
    181 } G_STMT_END
    182 
    183 #ifndef MIN
    184 	#define MIN(a, b) ((a) < (b) ? (a) : (b))
    185 #endif
    186 #ifndef MAX
    187 	#define MAX(a, b) ((a) > (b) ? (a) : (b))
    188 #endif
    189 
    190 #ifdef __cplusplus
    191 extern "C" {
    192 #endif
    193 
    194 typedef gpointer (*GNodeMapFunc)	(gpointer nodedata, gpointer data);
    195 
    196 /* debug functions */
    197 void debug_set_mode		(gboolean mode);
    198 gboolean debug_get_mode		(void);
    199 
    200 #ifdef HAVE_VA_OPT
    201 #define debug_print(format, ...) debug_print_real(__FILE__, __LINE__, format __VA_OPT__(,) __VA_ARGS__)
    202 #else
    203 #define debug_print \
    204 	debug_print_real("%s:%d:", debug_srcname(__FILE__), __LINE__), \
    205 	debug_print_real
    206 #endif
    207 
    208 /* for macro expansion */
    209 #define Str(x)	#x
    210 #define Xstr(x)	Str(x)
    211 
    212 /* String utilities.  */
    213 
    214 void list_free_strings_full		(GList		*list);
    215 void slist_free_strings_full	(GSList		*list);
    216 
    217 void hash_free_strings		(GHashTable	*table);
    218 
    219 gint str_case_equal		(gconstpointer	 v,
    220 				 gconstpointer	 v2);
    221 guint str_case_hash		(gconstpointer	 key);
    222 
    223 /* number-string conversion */
    224 gchar *itos_buf			(gchar	     *nstr,
    225 				 gint	      n);
    226 gchar *itos			(gint	      n);
    227 gchar *to_human_readable	(goffset      size);
    228 
    229 /* alternative string functions */
    230 gint path_cmp		(const gchar	*s1,
    231 			 const gchar	*s2);
    232 gchar *strretchomp	(gchar		*str);
    233 gchar *strtailchomp	(gchar		*str,
    234 			 gchar		 tail_char);
    235 gchar *strcrchomp	(gchar		*str);
    236 gchar *strcrlftrunc	(gchar *str);
    237 #ifndef HAVE_STRCASESTR
    238 gchar *strcasestr	(const gchar	*haystack,
    239 			 const gchar	*needle);
    240 #endif /* HAVE_STRCASESTR */
    241 gchar *strncasestr	(const gchar	*haystack,
    242 			 gint		 haystack_len,
    243 			 const gchar	*needle);
    244 gpointer my_memmem	(gconstpointer	 haystack,
    245 			 size_t		 haystacklen,
    246 			 gconstpointer	 needle,
    247 			 size_t		 needlelen);
    248 gchar *strncpy2		(gchar		*dest,
    249 			 const gchar	*src,
    250 			 size_t		 n);
    251 
    252 gboolean is_next_nonascii	(const gchar *s);
    253 gint get_next_word_len		(const gchar *s);
    254 
    255 /* functions for string parsing */
    256 gint subject_compare			(const gchar	*s1,
    257 					 const gchar	*s2);
    258 gint subject_compare_for_sort		(const gchar	*s1,
    259 					 const gchar	*s2);
    260 void trim_subject			(gchar		*str);
    261 void eliminate_parenthesis		(gchar		*str,
    262 					 gchar		 op,
    263 					 gchar		 cl);
    264 void extract_parenthesis		(gchar		*str,
    265 					 gchar		 op,
    266 					 gchar		 cl);
    267 
    268 void extract_quote			(gchar		*str,
    269 					 gchar		 quote_chr);
    270 gchar *escape_internal_quotes		(gchar		*str,
    271 					 gchar		 quote_chr);
    272 void eliminate_address_comment		(gchar		*str);
    273 gchar *strchr_with_skip_quote		(const gchar	*str,
    274 					 gint		 quote_chr,
    275 					 gint		 c);
    276 void extract_address			(gchar		*str);
    277 void extract_list_id_str		(gchar		*str);
    278 
    279 GSList *address_list_append		(GSList		*addr_list,
    280 					 const gchar	*str);
    281 GSList *address_list_append_with_comments(GSList	*addr_list,
    282 					 const gchar	*str);
    283 GSList *references_list_prepend		(GSList		*msgid_list,
    284 					 const gchar	*str);
    285 GSList *references_list_append		(GSList		*msgid_list,
    286 					 const gchar	*str);
    287 
    288 GList *add_history			(GList		*list,
    289 					 const gchar	*str);
    290 
    291 void remove_return			(gchar		*str);
    292 void remove_space			(gchar		*str);
    293 void unfold_line			(gchar		*str);
    294 void subst_char				(gchar		*str,
    295 					 gchar		 orig,
    296 					 gchar		 subst);
    297 void subst_chars			(gchar 		*str,
    298 					 gchar 		*orig,
    299 					 gchar 		subst);
    300 void subst_for_filename			(gchar		*str);
    301 void subst_for_shellsafe_filename	(gchar		*str);
    302 gboolean is_ascii_str			(const gchar	*str);
    303 gint check_line_length			(const gchar	*str,
    304 					 gint		 max_chars,
    305 					 gint		*line);
    306 
    307 gchar **strsplit_with_quote		(const gchar	*str,
    308 					 const gchar	*delim,
    309 					 gint		 max_tokens);
    310 
    311 gchar *trim_string			(const gchar	*str,
    312 					 gint		 len);
    313 
    314 GList *uri_list_extract_filenames	(const gchar	*uri_list);
    315 gboolean is_uri_string			(const gchar	*str);
    316 gchar *get_uri_path			(const gchar	*uri);
    317 gint get_uri_len			(const gchar	*str);
    318 void decode_uri				(gchar		*decoded_uri,
    319 					 const gchar	*encoded_uri);
    320 void decode_uri_with_plus		(gchar 		*decoded_uri,
    321 					 const gchar 	*encoded_uri,
    322 					 gboolean 	 with_plus);
    323 gint scan_mailto_url			(const gchar	*mailto,
    324 					 gchar	       **from,
    325 					 gchar	       **to,
    326 					 gchar	       **cc,
    327 					 gchar	       **bcc,
    328 					 gchar	       **subject,
    329 					 gchar	       **body,
    330 					 gchar	       ***attach,
    331 					 gchar	       **inreplyto);
    332 
    333 /* return static strings */
    334 const gchar *get_home_dir		(void);
    335 const gchar *get_rc_dir			(void);
    336 void  set_rc_dir			(const gchar *dir);
    337 gboolean rc_dir_is_alt			(void);
    338 const gchar *get_mail_base_dir		(void);
    339 const gchar *get_imap_cache_dir		(void);
    340 const gchar *get_mime_tmp_dir		(void);
    341 const gchar *get_template_dir		(void);
    342 const gchar *get_tmp_dir		(void);
    343 const gchar *get_locale_dir		(void);
    344 gchar *get_tmp_file			(void);
    345 const gchar *get_domain_name		(void);
    346 gboolean is_numeric_host_address	(const gchar *hostaddress);
    347 const gchar *get_desktop_file(void);
    348 
    349 /* file / directory handling */
    350 off_t get_file_size		(const gchar	*file);
    351 time_t get_file_mtime		(const gchar *file);
    352 
    353 gboolean file_exist		(const gchar	*file,
    354 				 gboolean	 allow_fifo);
    355 gboolean is_relative_filename   (const gchar *file);
    356 gboolean is_dir_exist		(const gchar	*dir);
    357 gboolean is_file_entry_exist	(const gchar	*file);
    358 gboolean is_file_entry_regular(const gchar *file);
    359 
    360 #define is_file_exist(file)		file_exist(file, FALSE)
    361 #define is_file_or_fifo_exist(file)	file_exist(file, TRUE)
    362 
    363 gint change_dir			(const gchar	*dir);
    364 gint make_dir_hier		(const gchar	*dir);
    365 gint remove_all_files		(const gchar	*dir);
    366 gint remove_numbered_files	(const gchar	*dir,
    367 				 guint		 first,
    368 				 guint		 last);
    369 gint remove_numbered_files_not_in_list(const gchar *dir,
    370 				       GSList *numberlist);
    371 gint remove_all_numbered_files	(const gchar	*dir);
    372 gint remove_dir_recursive	(const gchar	*dir);
    373 gchar *canonicalize_str		(const gchar	*str);
    374 gchar *normalize_newlines	(const gchar	*str);
    375 
    376 gchar *get_outgoing_rfc2822_str	(FILE		*fp);
    377 
    378 char *fgets_crlf(char *buf, int size, FILE *stream);
    379 
    380 /* process execution */
    381 gint execute_command_line	(const gchar	*cmdline,
    382 				 gboolean	 async,
    383 				 const gchar	*working_directory);
    384 gchar *get_command_output	(const gchar	*cmdline);
    385 FILE *get_command_output_stream	(const gchar	*cmdline);
    386 
    387 /* open URI with external browser */
    388 gint open_uri(const gchar *uri, const gchar *cmdline);
    389 /* open file with text editor */
    390 gint open_txt_editor(const gchar *filepath, const gchar *cmdline);
    391 
    392 /* time functions */
    393 time_t remote_tzoffset_sec	(const gchar	*zone);
    394 time_t tzoffset_sec		(time_t		*now);
    395 gchar *tzoffset			(time_t		*now);
    396 void get_rfc822_date		(gchar		*buf,
    397 				 gint		 len);
    398 void get_rfc822_date_hide_tz	(gchar		*buf,
    399 				 gint		 len);
    400 
    401 size_t fast_strftime		(gchar 			*buf,
    402 				 gint 			 buflen,
    403 				 const gchar 		*format,
    404 				 struct tm 		*lt);
    405 
    406 /* debugging */
    407 #ifdef HAVE_VA_OPT
    408 void debug_print_real (const char *file, int line, const gchar *format, ...) G_GNUC_PRINTF(3, 4);
    409 #else
    410 void debug_print_real (const gchar *format, ...) G_GNUC_PRINTF(1, 2);
    411 #endif
    412 const char * debug_srcname (const char *file);
    413 
    414 /* subject threading */
    415 void * subject_table_lookup(GHashTable *subject_table, gchar * subject);
    416 void subject_table_insert(GHashTable *subject_table, gchar * subject,
    417 			  void * data);
    418 void subject_table_remove(GHashTable *subject_table, gchar * subject);
    419 void utils_free_regex(void);
    420 gint subject_get_prefix_length (const gchar *subject);
    421 
    422 /* quoting recognition */
    423 const gchar * line_has_quote_char	(const gchar *str);
    424 
    425 gint g_int_compare	(gconstpointer a, gconstpointer b);
    426 
    427 gchar *generate_mime_boundary	(const gchar *prefix);
    428 
    429 gint quote_cmd_argument(gchar * result, guint size,
    430 			const gchar * path);
    431 GNode *g_node_map(GNode *node, GNodeMapFunc func, gpointer data);
    432 
    433 gboolean get_hex_value(guchar *out, gchar c1, gchar c2);
    434 void get_hex_str(gchar *out, guchar ch);
    435 
    436 /* auto pointer for containers that support GType system */
    437 
    438 #define G_TYPE_AUTO_POINTER	g_auto_pointer_register()
    439 typedef struct AutoPointer	GAuto;
    440 GType g_auto_pointer_register		(void);
    441 GAuto *g_auto_pointer_new		(gpointer pointer);
    442 GAuto *g_auto_pointer_new_with_free	(gpointer p,
    443 					 GFreeFunc free);
    444 gpointer g_auto_pointer_get_ptr		(GAuto *auto_ptr);
    445 GAuto *g_auto_pointer_copy		(GAuto *auto_ptr);
    446 void g_auto_pointer_free		(GAuto *auto_ptr);
    447 gboolean get_uri_part	(const gchar *start,
    448 		    	 const gchar *scanpos,
    449 		     	 const gchar **bp,
    450 		    	 const gchar **ep,
    451 		   	 gboolean hdr);
    452 gchar *make_uri_string	(const gchar *bp,
    453 			 const gchar *ep);
    454 gboolean get_email_part	(const gchar *start,
    455 			 const gchar *scanpos,
    456 			 const gchar **bp,
    457 			 const gchar **ep,
    458 			 gboolean hdr);
    459 gchar *make_email_string(const gchar *bp,
    460 			 const gchar *ep);
    461 gchar *make_http_string (const gchar *bp,
    462 			 const gchar *ep);
    463 
    464 gchar *mailcap_get_command_for_type(const gchar *type,
    465 				    const gchar *file_to_open);
    466 void mailcap_update_default	   (const gchar *type,
    467 				    const gchar *command);
    468 
    469 gboolean file_is_email(const gchar *filename);
    470 gboolean sc_g_list_bigger(GList *list, gint max);
    471 gboolean sc_g_slist_bigger(GSList *list, gint max);
    472 
    473 int cm_canonicalize_filename(const gchar *filename, gchar **canonical_name);
    474 
    475 guchar *g_base64_decode_zero(const gchar *text, gsize *out_len);
    476 
    477 gboolean get_random_bytes(void *buf, size_t count);
    478 
    479 #ifdef __cplusplus
    480 }
    481 #endif
    482 
    483 gboolean get_serverportfp_from_filename(const gchar *str, gchar **server, gchar **port, gchar **fp);
    484 
    485 #endif /* __UTILS_H__ */