/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999-2025 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
. */
#ifndef _MAILUTILS_UTIL_H
#define _MAILUTILS_UTIL_H
/* A collection of utility routines that don't belong somewhere else. */
#include
#include
#include
#include
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------- */
/* String manipulation */
/* ----------------------- */
unsigned long mu_hex2ul (char hex);
size_t mu_hexstr2ul (unsigned long* ul, const char* hex, size_t len);
size_t mu_cpystr (char *dst, const char *src, size_t size);
char *mu_stpcpy (char *p, const char *q);
int mu_string_unfold (char *text, size_t *plen);
int mu_true_answer_p (const char *p);
int mu_unre_set_regex (const char *str, int caseflag, char **errp);
int mu_unre_subject (const char *subject, const char **new_subject);
int mu_is_proto (const char *p);
int mu_mh_delim (const char *str);
void mu_str_url_decode_inline (char *str);
int mu_str_url_decode (char **ptr, const char *s);
/* ----------------------- */
/* File & path names. */
/* ----------------------- */
#define MU_HIERARCHY_DELIMITER '/'
char *mu_get_homedir (void);
char *mu_get_full_path (const char *file);
char *mu_normalize_path (char *path);
char *mu_expand_path_pattern (const char *pattern, const char *username);
char *mu_tilde_expansion (const char *ref, int delim,
const char *homedir);
int mu_readlink (const char *name, char **pbuf, size_t *psize, size_t *plen);
int mu_unroll_symlink (const char *name, char **pout);
char *mu_getcwd (void);
char *mu_make_file_name_suf (const char *dir, const char *file,
const char *suf);
#define mu_make_file_name(dir, file) mu_make_file_name_suf (dir, file, NULL)
/* ------------------------ */
/* Temporary file creation. */
/* ------------------------ */
#define MU_TEMPFILE_TMPDIR 0x01 /* tmpdir is set */
#define MU_TEMPFILE_SUFFIX 0x02 /* suffix is set */
#define MU_TEMPFILE_MKDIR 0x04 /* create a directory, not a file */
struct mu_tempfile_hints
{
char *tmpdir;
char *suffix;
};
/*int mu_tempfile (const char *tmpdir, char **namep);*/
int mu_tempfile (struct mu_tempfile_hints *hints, int flags,
int *pfd, char **namep);
char *mu_tempname (const char *tmpdir);
/* ----------------------- */
/* Current user email. */
/* ----------------------- */
/* Set the default user email address.
*
* Subsequent calls to mu_get_user_email() with a NULL name will return this
* email address. email is parsed to determine that it consists of a a valid
* rfc822 address, with one valid addr-spec, i.e, the address must be
* qualified.
*/
int mu_set_user_email (const char *email);
/* Set the default user email address domain.
*
* Subsequent calls to mu_get_user_email() with a non-null name will return
* email addresses in this domain (name@domain). It should be fully
* qualified, but this isn't (and can't) be enforced.
*/
int mu_set_user_email_domain (const char *domain);
/* Return the currently set user email domain, or NULL if not set. */
int mu_get_user_email_domain (const char** domain);
/* Same, but allocates memory */
int mu_aget_user_email_domain (char **pdomain);
/*
* Get the default email address for user name. A NULL name is taken
* to mean the current user.
*
* The result must be freed by the caller after use.
*/
char *mu_get_user_email (const char *name);
/* ----------------------- */
/* Message ID support. */
/* ----------------------- */
int mu_rfc2822_msg_id (int subpart, char **pstr);
int mu_rfc2822_references (mu_message_t msg, char **pstr);
int mu_rfc2822_in_reply_to (mu_message_t msg, char **pstr);
/* ----------------------- */
/* ----------------------- */
struct mu_content_type
{
char *type;
char *subtype;
char *trailer;
mu_assoc_t param;
};
typedef struct mu_content_type *mu_content_type_t;
#define MU_CONTENT_TYPE_STRICT 0x00
#define MU_CONTENT_TYPE_RELAXED 0x01
#define MU_CONTENT_TYPE_PARAM 0x02
int mu_content_type_parse (const char *input, const char *charset,
mu_content_type_t *retct);
int mu_content_type_parse_ext (const char *input, const char *charset,
int flags,
mu_content_type_t *retct);
void mu_content_type_destroy (mu_content_type_t *pptr);
int mu_content_type_format (mu_content_type_t ct, char **return_ptr);
/* ----------------------- */
/* Filter+iconv */
/* ----------------------- */
int mu_decode_filter (mu_stream_t *pfilter, mu_stream_t input,
const char *filter_type,
const char *fromcode, const char *tocode);
int mu_decode_filter_args (mu_stream_t *pfilter, mu_stream_t input,
const char *filter_name,
int argc, const char **argv,
const char *fromcode, const char *tocode);
extern enum mu_iconv_fallback_mode mu_default_fallback_mode;
int mu_set_default_fallback (const char *str);
/* ----------------------- */
/* Stream flags conversion */
/* ----------------------- */
int mu_stream_flags_to_mode (int flags, int isdir);
int mu_parse_stream_perm_string (int *pmode, const char *str,
const char **endp);
/* ----------------------- */
/* Stream-based getpass */
/* ----------------------- */
int mu_getpass (mu_stream_t in, mu_stream_t out, const char *prompt,
char **passptr);
/* ----------------------- */
/* String conversions. */
/* ----------------------- */
enum mu_c_type
{
mu_c_string,
mu_c_short,
mu_c_ushort,
mu_c_int,
mu_c_uint,
mu_c_long,
mu_c_ulong,
mu_c_size,
mu_c_hsize, /* mu_c_size with size suffix (KMG) allowed */
mu_c_off,
mu_c_time,
mu_c_bool,
mu_c_ipv4,
mu_c_cidr,
mu_c_host,
mu_c_incr, /* C int value, incremented each time mu_str_to_c is
invoked */
mu_c_void /* No type. Keep it the last */
};
typedef enum mu_c_type mu_c_type_t;
union mu_c_storage
{
char *c_string;
signed short c_short;
unsigned short c_ushort;
int c_int;
unsigned int c_uint;
long c_long;
unsigned long c_ulong;
size_t c_size;
mu_off_t c_off;
time_t c_time;
int c_bool;
struct mu_cidr c_cidr;
};
typedef union mu_c_storage mu_c_storage_t;
extern char const *mu_c_type_str[];
int mu_str_to_c (char const *string, mu_c_type_t type, void *tgt,
char **errmsg);
/* -------------------------- */
/* Safe file copy and rename */
/* -------------------------- */
/* Bits for the flags argument of mu_copy_file and mu_rename_file. The
MU_COPY_OVERWRITE is valid for both calls. The rest is for mu_copy_file
only */
#define MU_COPY_OVERWRITE 0x01 /* Overwrite destination file, if it exists */
#define MU_COPY_MODE 0x02 /* Preserve file mode */
#define MU_COPY_OWNER 0x04 /* Preserve file ownership */
#define MU_COPY_DEREF 0x08 /* Dereference the source file */
int mu_copy_file (const char *srcpath, const char *dstpath, int flags);
int mu_rename_file (const char *oldpath, const char *newpath, int flags);
int mu_remove_file (const char *path);
/* ----------------------- */
/* Assorted functions. */
/* ----------------------- */
int mu_file_name_is_safe (char const *str);
int mu_getmaxfd (void);
void mu_close_fds (int minfd);
int mu_daemon (void);
/* Get the host name, doing a getaddrinfo() if possible. */
int mu_get_host_name (char **host);
int mu_spawnvp (const char *prog, char *av[], int *stat);
int mu_set_user_privileges (uid_t uid, gid_t *gidv, size_t gidc);
int mu_switch_to_privs (uid_t uid, gid_t gid, mu_list_t retain_groups);
struct timeval;
int mu_fd_wait (int fd, int *pflags, struct timeval *tvp);
int mutil_parse_field_map (const char *map, mu_assoc_t *passoc_tab,
int *perr);
/* Run the onexit list */
void mu_onexit_run (void);
/* Reset the onexit list. */
void mu_onexit_reset (void);
/* Register the onexit function and associated data */
int mu_onexit (mu_onexit_t func, void *data);
#define MU_FILE_SAFETY_NONE 0x00
#define MU_FILE_SAFETY_OWNER_MISMATCH 0x01
#define MU_FILE_SAFETY_GROUP_WRITABLE 0x02
#define MU_FILE_SAFETY_WORLD_WRITABLE 0x04
#define MU_FILE_SAFETY_GROUP_READABLE 0x08
#define MU_FILE_SAFETY_WORLD_READABLE 0x10
#define MU_FILE_SAFETY_LINKED_WRDIR 0x20
#define MU_FILE_SAFETY_DIR_IWGRP 0x40
#define MU_FILE_SAFETY_DIR_IWOTH 0x80
#define MU_FILE_SAFETY_ALL ( \
MU_FILE_SAFETY_OWNER_MISMATCH | \
MU_FILE_SAFETY_GROUP_WRITABLE | \
MU_FILE_SAFETY_WORLD_WRITABLE | \
MU_FILE_SAFETY_GROUP_READABLE | \
MU_FILE_SAFETY_WORLD_READABLE | \
MU_FILE_SAFETY_LINKED_WRDIR | \
MU_FILE_SAFETY_DIR_IWGRP | \
MU_FILE_SAFETY_DIR_IWOTH )
int mu_file_safety_check (const char *filename, int mode,
uid_t uid,
mu_list_t idlist);
const char *mu_file_safety_code_to_name (int code);
int mu_file_safety_name_to_code (const char *name, int *pcode);
int mu_file_safety_name_to_error (const char *name, int *pcode);
int mu_file_safety_compose (int *res, const char *name, int defval);
int mu_file_mode_to_safety_criteria (int mode);
int mu_safety_criteria_to_file_mode (int crit);
#ifdef __cplusplus
}
#endif
#endif