2485072f4edd3272be89612957fe4f70ff0def13
[exim.git] / src / src / macro_predef.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) Jeremy Harris 2017 */
6 /* See the file NOTICE for conditions of use and distribution. */
7
8 /* Create a static data structure with the predefined macros, to be
9 included in the main Exim build */
10
11 #include "exim.h"
12 #include "macro_predef.h"
13
14 tree_node * tree_macros = NULL;
15 unsigned m_number = 1;
16
17 /* Global dummy variables */
18
19 void fn_smtp_receive_timeout(const uschar * name, const uschar * str) {}
20 uschar * syslog_facility_str;
21
22 /******************************************************************************/
23
24 void
25 builtin_macro_create_var(const uschar * name, const uschar * val)
26 {
27 macro_create(name, val, FALSE);
28 }
29
30
31 void
32 builtin_macro_create(const uschar * name)
33 {
34 builtin_macro_create_var(name, US"y");
35 }
36
37
38 /* restricted snprintf */
39 void
40 spf(uschar * buf, int len, const uschar * fmt, ...)
41 {
42 va_list ap;
43 va_start(ap, fmt);
44
45 while (*fmt && len > 1)
46   if (*fmt == '%' && fmt[1] == 'T')
47     {
48     uschar * s = va_arg(ap, uschar *);
49     while (*s && len-- > 1)
50       *buf++ = toupper(*s++);
51     fmt += 2;
52     }
53   else
54     {
55     *buf++ = *fmt++; len--;
56     }
57 *buf = '\0';
58 va_end(ap);
59 }
60
61 void
62 options_from_list(optionlist * opts, unsigned nopt,
63   const uschar * section, uschar * group)
64 {
65 int i;
66 const uschar * s;
67 uschar buf[64];
68
69 /* The 'previously-defined-substring' rule for macros in config file
70 lines is done thus for these builtin macros: we know that the table
71 we source from is in strict alpha order, hence the builtins portion
72 of the macros list is in reverse-alpha (we prepend them) - so longer
73 macros that have substrings are always discovered first during
74 expansion. */
75
76 for (i = 0; i < nopt; i++)  if (*(s = US opts[i].name) && *s != '*')
77   {
78   if (group)
79     spf(buf, sizeof(buf), CUS"_OPT_%T_%T_%T", section, group, s);
80   else
81     spf(buf, sizeof(buf), CUS"_OPT_%T_%T", section, s);
82   builtin_macro_create(buf);
83   }
84 }
85
86
87 /******************************************************************************/
88
89
90 /* Create compile-time feature macros */
91 static void
92 features(void)
93 {
94 /* Probably we could work out a static initialiser for wherever
95 macros are stored, but this will do for now. Some names are awkward
96 due to conflicts with other common macros. */
97
98 #ifdef SUPPORT_CRYPTEQ
99   builtin_macro_create(US"_HAVE_CRYPTEQ");
100 #endif
101 #if HAVE_ICONV
102   builtin_macro_create(US"_HAVE_ICONV");
103 #endif
104 #if HAVE_IPV6
105   builtin_macro_create(US"_HAVE_IPV6");
106 #endif
107 #ifdef HAVE_SETCLASSRESOURCES
108   builtin_macro_create(US"_HAVE_SETCLASSRESOURCES");
109 #endif
110 #ifdef SUPPORT_PAM
111   builtin_macro_create(US"_HAVE_PAM");
112 #endif
113 #ifdef EXIM_PERL
114   builtin_macro_create(US"_HAVE_PERL");
115 #endif
116 #ifdef EXPAND_DLFUNC
117   builtin_macro_create(US"_HAVE_DLFUNC");
118 #endif
119 #ifdef USE_TCP_WRAPPERS
120   builtin_macro_create(US"_HAVE_TCPWRAPPERS");
121 #endif
122 #ifdef SUPPORT_TLS
123   builtin_macro_create(US"_HAVE_TLS");
124 # ifdef USE_GNUTLS
125   builtin_macro_create(US"_HAVE_GNUTLS");
126 # else
127   builtin_macro_create(US"_HAVE_OPENSSL");
128 # endif
129 #endif
130 #ifdef SUPPORT_TRANSLATE_IP_ADDRESS
131   builtin_macro_create(US"_HAVE_TRANSLATE_IP_ADDRESS");
132 #endif
133 #ifdef SUPPORT_MOVE_FROZEN_MESSAGES
134   builtin_macro_create(US"_HAVE_MOVE_FROZEN_MESSAGES");
135 #endif
136 #ifdef WITH_CONTENT_SCAN
137   builtin_macro_create(US"_HAVE_CONTENT_SCANNING");
138 #endif
139 #ifndef DISABLE_DKIM
140   builtin_macro_create(US"_HAVE_DKIM");
141 #endif
142 #ifndef DISABLE_DNSSEC
143   builtin_macro_create(US"_HAVE_DNSSEC");
144 #endif
145 #ifndef DISABLE_EVENT
146   builtin_macro_create(US"_HAVE_EVENT");
147 #endif
148 #ifdef SUPPORT_I18N
149   builtin_macro_create(US"_HAVE_I18N");
150 #endif
151 #ifndef DISABLE_OCSP
152   builtin_macro_create(US"_HAVE_OCSP");
153 #endif
154 #ifndef DISABLE_PRDR
155   builtin_macro_create(US"_HAVE_PRDR");
156 #endif
157 #ifdef SUPPORT_PROXY
158   builtin_macro_create(US"_HAVE_PROXY");
159 #endif
160 #ifdef SUPPORT_SOCKS
161   builtin_macro_create(US"_HAVE_SOCKS");
162 #endif
163 #ifdef TCP_FASTOPEN
164   builtin_macro_create(US"_HAVE_TCP_FASTOPEN");
165 #endif
166 #ifdef EXPERIMENTAL_LMDB
167   builtin_macro_create(US"_HAVE_LMDB");
168 #endif
169 #ifdef SUPPORT_SPF
170   builtin_macro_create(US"_HAVE_SPF");
171 #endif
172 #ifdef EXPERIMENTAL_SRS
173   builtin_macro_create(US"_HAVE_SRS");
174 #endif
175 #ifdef EXPERIMENTAL_BRIGHTMAIL
176   builtin_macro_create(US"_HAVE_BRIGHTMAIL");
177 #endif
178 #ifdef EXPERIMENTAL_DANE
179   builtin_macro_create(US"_HAVE_DANE");
180 #endif
181 #ifdef EXPERIMENTAL_DCC
182   builtin_macro_create(US"_HAVE_DCC");
183 #endif
184 #ifdef EXPERIMENTAL_DMARC
185   builtin_macro_create(US"_HAVE_DMARC");
186 #endif
187 #ifdef EXPERIMENTAL_DSN_INFO
188   builtin_macro_create(US"_HAVE_DSN_INFO");
189 #endif
190
191 #ifdef LOOKUP_LSEARCH
192   builtin_macro_create(US"_HAVE_LOOKUP_LSEARCH");
193 #endif
194 #ifdef LOOKUP_CDB
195   builtin_macro_create(US"_HAVE_LOOKUP_CDB");
196 #endif
197 #ifdef LOOKUP_DBM
198   builtin_macro_create(US"_HAVE_LOOKUP_DBM");
199 #endif
200 #ifdef LOOKUP_DNSDB
201   builtin_macro_create(US"_HAVE_LOOKUP_DNSDB");
202 #endif
203 #ifdef LOOKUP_DSEARCH
204   builtin_macro_create(US"_HAVE_LOOKUP_DSEARCH");
205 #endif
206 #ifdef LOOKUP_IBASE
207   builtin_macro_create(US"_HAVE_LOOKUP_IBASE");
208 #endif
209 #ifdef LOOKUP_LDAP
210   builtin_macro_create(US"_HAVE_LOOKUP_LDAP");
211 #endif
212 #ifdef EXPERIMENTAL_LMDB
213   builtin_macro_create(US"_HAVE_LOOKUP_LMDB");
214 #endif
215 #ifdef LOOKUP_MYSQL
216   builtin_macro_create(US"_HAVE_LOOKUP_MYSQL");
217 #endif
218 #ifdef LOOKUP_NIS
219   builtin_macro_create(US"_HAVE_LOOKUP_NIS");
220 #endif
221 #ifdef LOOKUP_NISPLUS
222   builtin_macro_create(US"_HAVE_LOOKUP_NISPLUS");
223 #endif
224 #ifdef LOOKUP_ORACLE
225   builtin_macro_create(US"_HAVE_LOOKUP_ORACLE");
226 #endif
227 #ifdef LOOKUP_PASSWD
228   builtin_macro_create(US"_HAVE_LOOKUP_PASSWD");
229 #endif
230 #ifdef LOOKUP_PGSQL
231   builtin_macro_create(US"_HAVE_LOOKUP_PGSQL");
232 #endif
233 #ifdef LOOKUP_REDIS
234   builtin_macro_create(US"_HAVE_LOOKUP_REDIS");
235 #endif
236 #ifdef LOOKUP_SQLITE
237   builtin_macro_create(US"_HAVE_LOOKUP_SQLITE");
238 #endif
239 #ifdef LOOKUP_TESTDB
240   builtin_macro_create(US"_HAVE_LOOKUP_TESTDB");
241 #endif
242 #ifdef LOOKUP_WHOSON
243   builtin_macro_create(US"_HAVE_LOOKUP_WHOSON");
244 #endif
245
246 #ifdef TRANSPORT_APPENDFILE
247 # ifdef SUPPORT_MAILDIR
248   builtin_macro_create(US"_HAVE_TRANSPORT_APPEND_MAILDIR");
249 # endif
250 # ifdef SUPPORT_MAILSTORE
251   builtin_macro_create(US"_HAVE_TRANSPORT_APPEND_MAILSTORE");
252 # endif
253 # ifdef SUPPORT_MBX
254   builtin_macro_create(US"_HAVE_TRANSPORT_APPEND_MBX");
255 # endif
256 #endif
257
258 #ifdef WITH_CONTENT_SCAN
259 features_malware();
260 #endif
261
262 features_crypto();
263 }
264
265
266 static void
267 options(void)
268 {
269 options_main();
270 options_routers();
271 options_transports();
272 options_auths();
273 }
274
275 static void
276 params(void)
277 {
278 #ifndef DISABLE_DKIM
279 params_dkim();
280 #endif
281 }
282
283
284 static unsigned
285 macro_dump(macro_item * m)
286 {
287 int left = 0, right = 0;
288 tree_node * t;
289 macro_item_64 * m64;
290
291 /* fprintf(stderr, "%s %p\n", __FUNCTION__, m); */
292
293 if (!m) return 0;
294 /* fprintf(stderr, "%s '%s' l %p r %p\n", __FUNCTION__, m->tnode.name, m->tnode.left, m->tnode.left); */
295 if ((t = m->tnode.left)) left = macro_dump(tnode_to_mitem(m->tnode.left));
296 if ((t = m->tnode.right)) right = macro_dump(tnode_to_mitem(m->tnode.right));
297
298 printf ("static macro_item_64 p%u = { ", m->m_number);
299 printf(" .command_line=FALSE,"
300        " .namelen=%d,"
301        " .replen=%d,"
302        " .m_number=%u,"
303        " .tnode={",
304         Ustrlen(m->tnode.name), Ustrlen(m->tnode.data.ptr), m->m_number);
305 printf(left  ? " .left=&p%d.tnode,"  : " .left=NULL,",  left);
306 printf(right ? " .right=&p%d.tnode," : " .right=NULL,", right);
307 printf(
308         " .data.ptr=\"%s\","
309         " .balance=%d,"
310         " .name=\"%s\"}};\n",
311         CS m->tnode.data.ptr,
312         m->tnode.balance,
313         CS m->tnode.name);
314
315 if (Ustrlen(m->tnode.name) +1 > sizeof(m64->tnode.name))
316   {
317   printf("#error macro name too long for macro_item_64\n");
318   exit(1);
319   }
320 return m->m_number;
321 }
322
323
324
325 int
326 main(void)
327 {
328 unsigned idx;
329
330 printf("#include \"exim.h\"\n");
331 features();
332 options();
333 params();
334
335 idx = macro_dump(tnode_to_mitem(tree_macros));
336 printf("tree_node * tree_macros = (tree_node *) &p%u.tnode;\n", idx);
337 printf("unsigned m_number = %u;\n", m_number);
338 exit(0);
339 }