/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2016-2021 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils. If not, see . */
#include
#include
#include
#include
#include
/* Examines STR for occurrences of characters from CHR. Returns in RET_STR
a malloc'ed string where each occurrence of CHR[i] is replaced by a
backslash, followed by XTAB[i].
If CHR is NULL, RET_STR contains a malloc'ed copy of STR (XTAB is
ignored).
If XTAB is NULL, XTAB = CHR is assumed.
Callers are advised to include backslash into both CHR and XTAB.
Returns 0 on success, error code if an error occurred.
Example:
Escape each occurrence of backslash and double quote:
mu_c_str_escape (str, "\\\"", NULL, &ret_str)
*/
int
mu_c_str_escape (char const *str, char const *chr, char const *xtab,
char **ret_str)
{
char *newstr;
size_t n;
int c;
if (!ret_str)
return MU_ERR_OUT_PTR_NULL;
if (!str)
{
*ret_str = NULL;
return 0;
}
if (!chr)
{
newstr = strdup (str);
if (!newstr)
return errno;
*ret_str = newstr;
return 0;
}
n = strlen (chr);
if (xtab)
{
if (strlen (xtab) != n)
return EINVAL;
}
else
xtab = chr;
n = mu_str_count (str, chr, NULL);
newstr = malloc (strlen (str) + n + 1);
if (!newstr)
return errno;
*ret_str = newstr;
if (n == 0)
{
strcpy (newstr, str);
return 0;
}
while ((c = *str++) != 0)
{
char *p = strchr (chr, c);
if (p)
{
*newstr++ = '\\';
*newstr++ = xtab[p - chr];
}
else
*newstr++ = c;
}
*newstr = 0;
return 0;
}
/* Escape certain characters in STR. Return allocated string in RET_STR.
Escapable characters are defined by the array TRANS, which consists of an
even number of elements. Each pair of characters in this array contains:
TRANS[i+1] - character to be escaped
TRANS[i] - character to use in escape sequence for TRANS[i+1].
Each TRANS[i+1] is replaced by backslash + TRANS[i].
Returns 0 on success, or error code if an error occurred.
E.g., to escape control characters, backslash and double-quote using
C convention:
mu_c_str_escape_trans (str, "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v", &ret)
See also mu_wordsplit_c_escape_tab in wordsplit.c
*/
int
mu_c_str_escape_trans (char const *str, char const *trans, char **ret_str)
{
char *chr, *xtab;
size_t n, i;
int rc;
if (trans)
{
n = strlen (trans);
if (n % 2)
return EINVAL;
chr = malloc (n + 2);
if (!chr)
return errno;
xtab = chr + n / 2 + 1;
for (i = 0; i < n; i += 2)
{
chr[i / 2] = trans[i + 1];
xtab[i / 2] = trans[i];
}
chr[i / 2] = xtab[i / 2] = 0;
}
else
{
chr = xtab = NULL;
}
rc = mu_c_str_escape (str, chr, xtab, ret_str);
free (chr);
return rc;
}