1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2005-2021 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils 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
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <string.h>
24
25 #include <mailutils/mailutils.h>
26
27 /* Replace all octal escapes in BUF with the corresponding characters. */
28 static void
decode_octal(char * buf)29 decode_octal (char *buf)
30 {
31 char *p;
32 unsigned i, n;
33
34 for (p = buf; *p;)
35 {
36 if (*buf == '\\')
37 {
38 buf++;
39 switch (*buf)
40 {
41 case 'a':
42 *p++ = '\a';
43 buf++;
44 break;
45
46 case 'b':
47 *p++ = '\b';
48 buf++;
49 break;
50
51 case 'f':
52 *p++ = '\f';
53 buf++;
54 break;
55
56 case 'n':
57 *p++ = '\n';
58 buf++;
59 break;
60
61 case 'r':
62 *p++ = '\r';
63 buf++;
64 break;
65
66 case 't':
67 *p++ = '\t';
68 buf++;
69 break;
70
71 case '0': case '1': case '2': case '3':
72 case '4': case '5': case '6': case '7':
73 n = 0;
74 for (i = 0; i < 3; i++, buf++)
75 {
76 unsigned x = *(unsigned char*)buf - '0';
77 if (x > 7)
78 break;
79 n <<= 3;
80 n += x;
81 }
82 if (i != 3)
83 {
84 buf -= i;
85 *p++ = '\\';
86 }
87 else
88 *p++ = n;
89 break;
90
91 default:
92 *p++ = '\\';
93 *p++ = *buf++;
94 break;
95 }
96 }
97 else
98 *p++ = *buf++;
99 }
100 *p = 0;
101 }
102
103 int
main(int argc,char * argv[])104 main (int argc, char *argv[])
105 {
106 int rc;
107 char *buf = NULL;
108 size_t size = 0;
109 size_t n;
110 char *charset = "iso-8859-1";
111 char *encoding = "quoted-printable";
112 int octal = 0;
113 struct mu_option options[] = {
114 { "charset", 'c', "NAME", MU_OPTION_DEFAULT,
115 "define input character set", mu_c_string, &charset },
116 { "encoding", 'e', "NAME", MU_OPTION_DEFAULT,
117 "define input encoding", mu_c_string, &encoding },
118 { "octal", 'o', NULL, MU_OPTION_DEFAULT,
119 "decode octal escape notations on input", mu_c_bool, &octal },
120 MU_OPTION_END
121 };
122
123 mu_set_program_name (argv[0]);
124 mu_stdstream_setup (MU_STDSTREAM_RESET_NONE);
125 mu_cli_simple (argc, argv,
126 MU_CLI_OPTION_OPTIONS, options,
127 MU_CLI_OPTION_PROG_DOC, "Test RFC 2047 encoding function",
128 MU_CLI_OPTION_EXTRA_INFO, "Defaults are: --charset=iso-8859-1 --encoding=quoted-printable",
129 MU_CLI_OPTION_END);
130
131 while ((rc = mu_stream_getline (mu_strin, &buf, &size, &n)) == 0 && n > 0)
132 {
133 char *p;
134
135 mu_rtrim_class (buf, MU_CTYPE_ENDLN);
136 if (octal)
137 decode_octal (buf);
138
139 rc = mu_rfc2047_encode (charset, encoding, buf, &p);
140 if (rc)
141 mu_diag_funcall (MU_DIAG_ERROR, "mu_rfc2047_encode", NULL, rc);
142 else if (p)
143 mu_printf ("%s\n", p);
144 free (p);
145 }
146 if (rc)
147 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_getline", NULL, rc);
148 return 0;
149 }
150