1 /* GNU Mailutils -- a suite of utilities for electronic mail
2    Copyright (C) 1999-2021 Free Software Foundation, Inc.
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 3 of the License, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General
15    Public License along with this library.  If not, see
16    <http://www.gnu.org/licenses/>. */
17 
18 #ifndef _MAILUTILS_UTIL_H
19 #define _MAILUTILS_UTIL_H
20 
21 /* A collection of utility routines that don't belong somewhere else. */
22 
23 #include <mailutils/list.h>
24 #include <mailutils/types.h>
25 #include <mailutils/cidr.h>
26 #include <mailutils/filter.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32   /* ----------------------- */
33   /* String manipulation     */
34   /* ----------------------- */
35 unsigned long mu_hex2ul (char hex);
36 size_t mu_hexstr2ul (unsigned long* ul, const char* hex, size_t len);
37 size_t mu_cpystr (char *dst, const char *src, size_t size);
38 char *mu_stpcpy (char *p, const char *q);
39 int mu_string_unfold (char *text, size_t *plen);
40 int mu_true_answer_p (const char *p);
41 int mu_unre_set_regex (const char *str, int caseflag, char **errp);
42 int mu_unre_subject  (const char *subject, const char **new_subject);
43 int mu_is_proto (const char *p);
44 int mu_mh_delim (const char *str);
45 void mu_str_url_decode_inline (char *str);
46 int mu_str_url_decode (char **ptr, const char *s);
47 
48   /* ----------------------- */
49   /* File & path names.      */
50   /* ----------------------- */
51 
52 #define MU_HIERARCHY_DELIMITER '/'
53 
54 char *mu_get_homedir (void);
55 char *mu_get_full_path (const char *file);
56 char *mu_normalize_path (char *path);
57 char *mu_expand_path_pattern (const char *pattern, const char *username);
58 char *mu_tilde_expansion (const char *ref, int delim,
59 			  const char *homedir);
60 int mu_readlink (const char *name, char **pbuf, size_t *psize, size_t *plen);
61 int mu_unroll_symlink (const char *name, char **pout);
62 char *mu_getcwd (void);
63 char *mu_make_file_name_suf (const char *dir, const char *file,
64 			     const char *suf);
65 #define mu_make_file_name(dir, file) mu_make_file_name_suf (dir, file, NULL)
66 
67   /* ------------------------ */
68   /* Temporary file creation. */
69   /* ------------------------ */
70 #define MU_TEMPFILE_TMPDIR  0x01   /* tmpdir is set */
71 #define MU_TEMPFILE_SUFFIX  0x02   /* suffix is set */
72 #define MU_TEMPFILE_MKDIR   0x04   /* create a directory, not a file */
73 
74 struct mu_tempfile_hints
75 {
76   char *tmpdir;
77   char *suffix;
78 };
79 
80   /*int mu_tempfile (const char *tmpdir, char **namep);*/
81 int mu_tempfile (struct mu_tempfile_hints *hints, int flags,
82 		 int *pfd, char **namep);
83 char *mu_tempname (const char *tmpdir);
84 
85   /* ----------------------- */
86   /* Current user email.     */
87   /* ----------------------- */
88 /* Set the default user email address.
89  *
90  * Subsequent calls to mu_get_user_email() with a NULL name will return this
91  * email address.  email is parsed to determine that it consists of a a valid
92  * rfc822 address, with one valid addr-spec, i.e, the address must be
93  * qualified.
94  */
95 int mu_set_user_email (const char *email);
96 
97 /* Set the default user email address domain.
98  *
99  * Subsequent calls to mu_get_user_email() with a non-null name will return
100  * email addresses in this domain (name@domain). It should be fully
101  * qualified, but this isn't (and can't) be enforced.
102  */
103 int mu_set_user_email_domain (const char *domain);
104 
105 /* Return the currently set user email domain, or NULL if not set. */
106 int mu_get_user_email_domain (const char** domain);
107 
108 /* Same, but allocates memory */
109 int mu_aget_user_email_domain (char **pdomain);
110 
111 /*
112  * Get the default email address for user name. A NULL name is taken
113  * to mean the current user.
114  *
115  * The result must be freed by the caller after use.
116  */
117 char *mu_get_user_email (const char *name);
118 
119   /* ----------------------- */
120   /* Message ID support.     */
121   /* ----------------------- */
122 
123 int mu_rfc2822_msg_id (int subpart, char **pstr);
124 int mu_rfc2822_references (mu_message_t msg, char **pstr);
125 int mu_rfc2822_in_reply_to (mu_message_t msg, char **pstr);
126 
127   /* ----------------------- */
128   /* ----------------------- */
129 struct mu_content_type
130 {
131   char *type;
132   char *subtype;
133   char *trailer;
134   mu_assoc_t param;
135 };
136 
137 typedef struct mu_content_type *mu_content_type_t;
138 
139 #define MU_CONTENT_TYPE_STRICT   0x00
140 #define MU_CONTENT_TYPE_RELAXED  0x01
141 #define MU_CONTENT_TYPE_PARAM    0x02
142 
143 int mu_content_type_parse (const char *input, const char *charset,
144 			   mu_content_type_t *retct);
145 int mu_content_type_parse_ext (const char *input, const char *charset,
146 			       int flags,
147 			       mu_content_type_t *retct);
148 void mu_content_type_destroy (mu_content_type_t *pptr);
149 
150 int mu_content_type_format (mu_content_type_t ct, char **return_ptr);
151 
152   /* ----------------------- */
153   /* Filter+iconv            */
154   /* ----------------------- */
155 int mu_decode_filter (mu_stream_t *pfilter, mu_stream_t input,
156 		      const char *filter_type,
157 		      const char *fromcode, const char *tocode);
158 int mu_decode_filter_args (mu_stream_t *pfilter, mu_stream_t input,
159 			   const char *filter_name,
160 			   int argc, const char **argv,
161 			   const char *fromcode, const char *tocode);
162 
163 extern enum mu_iconv_fallback_mode mu_default_fallback_mode;
164 int mu_set_default_fallback (const char *str);
165 
166   /* ----------------------- */
167   /* Stream flags conversion */
168   /* ----------------------- */
169 int mu_stream_flags_to_mode (int flags, int isdir);
170 int mu_parse_stream_perm_string (int *pmode, const char *str,
171 				 const char **endp);
172 
173 
174   /* ----------------------- */
175   /* Stream-based getpass    */
176   /* ----------------------- */
177 int mu_getpass (mu_stream_t in, mu_stream_t out, const char *prompt,
178 		char **passptr);
179 
180   /* ----------------------- */
181   /* String conversions.     */
182   /* ----------------------- */
183 
184 enum mu_c_type
185   {
186     mu_c_string,
187     mu_c_short,
188     mu_c_ushort,
189     mu_c_int,
190     mu_c_uint,
191     mu_c_long,
192     mu_c_ulong,
193     mu_c_size,
194     mu_c_hsize,       /* mu_c_size with size suffix (KMG) allowed */
195     mu_c_off,
196     mu_c_time,
197     mu_c_bool,
198     mu_c_ipv4,
199     mu_c_cidr,
200     mu_c_host,
201     mu_c_incr,        /* C int value, incremented each time mu_str_to_c is
202 			 invoked */
203     mu_c_void         /* No type.  Keep it the last */
204   };
205 
206 typedef enum mu_c_type mu_c_type_t;
207 
208 union mu_c_storage
209 {
210   char *c_string;
211   signed short c_short;
212   unsigned short c_ushort;
213   int c_int;
214   unsigned int c_uint;
215   long c_long;
216   unsigned long c_ulong;
217   size_t c_size;
218   mu_off_t c_off;
219   time_t c_time;
220   int c_bool;
221   struct mu_cidr c_cidr;
222 };
223 
224 typedef union mu_c_storage mu_c_storage_t;
225 
226 extern char const *mu_c_type_str[];
227 int mu_str_to_c (char const *string, mu_c_type_t type, void *tgt,
228 		 char **errmsg);
229 
230   /* -------------------------- */
231   /* Safe file copy and rename  */
232   /* -------------------------- */
233 /* Bits for the flags argument of mu_copy_file and mu_rename_file.  The
234    MU_COPY_OVERWRITE is valid for both calls.  The rest is for mu_copy_file
235    only */
236 #define MU_COPY_OVERWRITE 0x01 /* Overwrite destination file, if it exists */
237 #define MU_COPY_MODE      0x02 /* Preserve file mode */
238 #define MU_COPY_OWNER     0x04 /* Preserve file ownership */
239 #define MU_COPY_DEREF     0x08 /* Dereference the source file */
240 
241 int mu_copy_file (const char *srcpath, const char *dstpath, int flags);
242 int mu_rename_file (const char *oldpath, const char *newpath, int flags);
243 int mu_remove_file (const char *path);
244 
245   /* ----------------------- */
246   /* Assorted functions.     */
247   /* ----------------------- */
248 int mu_file_name_is_safe (char const *str);
249 
250 int mu_getmaxfd (void);
251 void mu_close_fds (int minfd);
252 int mu_daemon (void);
253 
254 /* Get the host name, doing a gethostbyname() if possible. */
255 int mu_get_host_name (char **host);
256 int mu_spawnvp (const char *prog, char *av[], int *stat);
257 int mu_set_user_privileges (uid_t uid, gid_t *gidv, size_t gidc);
258 int mu_switch_to_privs (uid_t uid, gid_t gid, mu_list_t retain_groups);
259 
260 struct timeval;
261 int mu_fd_wait (int fd, int *pflags, struct timeval *tvp);
262 
263 
264 int mutil_parse_field_map (const char *map, mu_assoc_t *passoc_tab,
265 			   int *perr);
266 
267 /* Run the onexit list */
268 void mu_onexit_run (void);
269 /* Reset the onexit list. */
270 void mu_onexit_reset (void);
271 /* Register the onexit function and associated data */
272 int mu_onexit (mu_onexit_t func, void *data);
273 
274 #define MU_FILE_SAFETY_NONE           0x00
275 #define MU_FILE_SAFETY_OWNER_MISMATCH 0x01
276 #define MU_FILE_SAFETY_GROUP_WRITABLE 0x02
277 #define MU_FILE_SAFETY_WORLD_WRITABLE 0x04
278 #define MU_FILE_SAFETY_GROUP_READABLE 0x08
279 #define MU_FILE_SAFETY_WORLD_READABLE 0x10
280 #define MU_FILE_SAFETY_LINKED_WRDIR   0x20
281 #define MU_FILE_SAFETY_DIR_IWGRP      0x40
282 #define MU_FILE_SAFETY_DIR_IWOTH      0x80
283 
284 #define MU_FILE_SAFETY_ALL      (		\
285   MU_FILE_SAFETY_OWNER_MISMATCH |		\
286   MU_FILE_SAFETY_GROUP_WRITABLE |		\
287   MU_FILE_SAFETY_WORLD_WRITABLE |		\
288   MU_FILE_SAFETY_GROUP_READABLE |		\
289   MU_FILE_SAFETY_WORLD_READABLE |		\
290   MU_FILE_SAFETY_LINKED_WRDIR   |		\
291   MU_FILE_SAFETY_DIR_IWGRP      |		\
292   MU_FILE_SAFETY_DIR_IWOTH      )
293 
294 
295 int mu_file_safety_check (const char *filename, int mode,
296 			  uid_t uid,
297 			  mu_list_t idlist);
298 const char *mu_file_safety_code_to_name (int code);
299 int mu_file_safety_name_to_code (const char *name, int *pcode);
300 int mu_file_safety_name_to_error (const char *name, int *pcode);
301 int mu_file_safety_compose (int *res, const char *name, int defval);
302 
303 int mu_file_mode_to_safety_criteria (int mode);
304 int mu_safety_criteria_to_file_mode (int crit);
305 
306 #ifdef __cplusplus
307 }
308 #endif
309 
310 #endif
311 
312