Skip the Cygwin package (.bz2) file when searching for the input (.gz) file.
[mmh] / sbr / escape_display_name.c
1 /*
2  * escape_display_name.c -- Escape a display name, hopefully per RFC 5322.
3  *
4  * This code is Copyright (c) 2012, by the authors of nmh.  See the
5  * COPYRIGHT file in the root directory of the nmh distribution for
6  * complete copyright information.
7  */
8
9 #include <sys/types.h>
10 #include <h/utils.h>
11 #include <string.h>
12 #include <stdlib.h>
13
14 /* Escape a display name, hopefully per RFC 5322.  Assumes one-byte
15    characters.  The char array pointed to by the name argument is
16    modified in place.  Its size is specified by the namesize
17    argument. */
18 void
19 escape_display_name (char *name, size_t namesize) {
20     /* Quote and escape name that contains any specials, as necessary. */
21     if (strpbrk("\"(),.:;<>@[\\]", name)) {
22         char *destp, *srcp;
23         /* Maximum space requirement would be if each character had
24            to be escaped, plus enclosing double quotes, plus null termintor.
25            E.g., 2 characters, "", would require 7, "\"\""0, where that 0
26            is '\0'. */
27         char *tmp = mh_xmalloc (2*strlen(name) + 3);
28
29         for (destp = tmp, srcp = name; *srcp; ++srcp) {
30             if (srcp == name) {
31                 /* Insert initial double quote, if needed. */
32                 if (*srcp != '"') {
33                     *destp++ = '"';
34                 }
35             } else {
36                 /* Escape embedded, unescaped double quote. */
37                 if (*srcp == '"' && *(srcp+1) != '\0' && *(srcp-1) != '\\') {
38                     *destp++ = '\\';
39                 }
40             }
41
42             *destp++ = *srcp;
43
44             /* End of name. */
45             if (*(srcp+1) == '\0') {
46                 /* Insert final double quote, if needed. */
47                 if (*srcp != '"') {
48                     *destp++ = '"';
49                 }
50
51                 *destp++ = '\0';
52             }
53         }
54
55         if (strcmp (tmp, "\"")) {
56             /* assert (strlen(tmp) + 1 == destp - tmp); */
57             size_t len = destp - tmp;
58             strncpy (name, tmp, len <= namesize  ?  len  :  namesize);
59         } else {
60             /* Handle just " as special case here instead of above. */
61             strncpy (name, "\"\\\"\"", namesize);
62         }
63
64         name[namesize - 1] = '\0';
65
66         free (tmp);
67     }
68 }