Use project-standard memory management rather than alloca()
[exim.git] / src / exim_monitor / em_init.c
1 /*************************************************
2 *                  Exim monitor                  *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2009 */
6 /* Copyright (c) The Exim Maintainers 2020 - 2021 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
9
10 /* This module contains code to initialize things from the
11 environment and the arguments. */
12
13
14 #include "em_hdr.h"
15
16
17
18 /*************************************************
19 *            Decode stripchart config            *
20 *************************************************/
21
22 /* First determine how many are requested, then compile the
23 regular expressions and save the title strings. Note that
24 stripchart_number is initialized to 1 or 2 to count the always-
25 present queue stripchart, and the optional size-monitoring
26 stripchart. */
27
28 static void decode_stripchart_config(uschar *s)
29 {
30 int i;
31
32 /* Loop: first time just counts, second time does the
33 work. */
34
35 for (i = 0; i <= 1; i++)
36   {
37   int first = 1;
38   int count = 0;
39   uschar *p = s;
40
41   if (*p == '/') p++;   /* allow optional / at start */
42
43   /* This loops for all the substrings, using the first flag
44   to determine whether each is the first or second of the pairs. */
45
46   while (*p)
47     {
48     uschar *pp;
49     /* Handle continuations */
50     if (*p == '\n')
51       {
52       while (*(++p) == ' ' || *p == '\t');
53       if (*p == '/') p++;
54       }
55
56     /* Find the end of the string and count if first string */
57
58     pp = p;
59     while (*p && *p != '/') p++;
60     if (first) count++;
61
62     /* Take action on the second time round. */
63
64     if (i != 0)
65       {
66       uschar buffer[256];
67       int indx = count + stripchart_varstart - 1;
68       Ustrncpy(buffer, pp, p-pp);
69       buffer[p-pp] = 0;
70       if (first)
71         {
72         size_t offset;
73         int err;
74
75         if (!(stripchart_regex[indx] =
76                 pcre2_compile((PCRE2_SPTR)buffer,
77                       PCRE2_ZERO_TERMINATED, PCRE_COPT,
78                       &err, &offset, NULL)))
79           {
80           uschar errbuf[128];
81           pcre2_get_error_message(err, errbuf, sizeof(errbuf));
82           printf("regular expression error: %s at offset %ld "
83             "while compiling %s\n", errbuf, (long)offset, buffer);
84           exit(99);
85           }
86         }
87       else stripchart_title[indx] = string_copy(buffer);
88       }
89
90     /* Advance past the delimiter and flip the first/second flag */
91
92     p++;
93     first = !first;
94     }
95
96   /* On the first pass, we now know the number of stripcharts. Get
97   store for holding the pointers to the regular expressions and
98   title strings. */
99
100   if (i == 0)
101     {
102     stripchart_number += count;
103     stripchart_regex = (pcre2_code **)store_malloc(stripchart_number * sizeof(pcre2_code *));
104     stripchart_title = (uschar **)store_malloc(stripchart_number * sizeof(uschar *));
105     }
106   }
107 }
108
109
110 /*************************************************
111 *                    Initialize                  *
112 *************************************************/
113
114 void init(int argc, uschar **argv)
115 {
116 int x;
117 size_t erroroffset;
118 uschar *s;
119
120 argc = argc;     /* These are currently unused. */
121 argv = argv;
122
123 /* Deal with simple values in the environment. */
124
125 if ((s = US getenv("ACTION_OUTPUT")))
126   {
127   if (Ustrcmp(s, "no") == 0) action_output = FALSE;
128   if (Ustrcmp(s, "yes") == 0) action_output = TRUE;
129   }
130
131 if ((s = US getenv("ACTION_QUEUE_UPDATE")))
132   {
133   if (Ustrcmp(s, "no") == 0) action_queue_update = FALSE;
134   if (Ustrcmp(s, "yes") == 0) action_queue_update = TRUE;
135   }
136
137 s = US getenv("BODY_MAX");
138 if (s && (x = Uatoi(s)) != 0) body_max = x;
139
140 if ((s = US getenv("EXIM_PATH")))
141   exim_path = string_copy(s);
142
143 if ((s = US getenv("EXIMON_EXIM_CONFIG")))
144   alternate_config = string_copy(s);
145
146 if ((s = US getenv("LOG_BUFFER")))
147   {
148   uschar c[1];
149   if (sscanf(CS s, "%d%c", &x, c) > 0)
150     {
151     if (c[0] == 'K' || c[0] == 'k') x *= 1024;
152     if (x < 1024) x = 1024;
153     log_buffer_size = x;
154     }
155   }
156
157 s = US getenv("LOG_DEPTH");
158 if (s && (x = Uatoi(s)) != 0) log_depth = x;
159
160 if ((s = US getenv("LOG_FILE_NAME")))
161   log_file = string_copy(s);
162
163 if ((s = US getenv("LOG_FONT")))
164   log_font = string_copy(s);
165
166 s = US getenv("LOG_WIDTH");
167 if (s && (x = Uatoi(s)) != 0) log_width = x;
168
169 if ((s = US getenv("MENU_EVENT")))
170   menu_event = string_copy(s);
171
172 s = US getenv("MIN_HEIGHT");
173 if (s && (x = Uatoi(s)) > 0) min_height = x;
174
175 s = US getenv("MIN_WIDTH");
176 if (s && (x = Uatoi(s)) > 0) min_width = x;
177
178 if ((s = US getenv("QUALIFY_DOMAIN")))
179   qualify_domain = string_copy(s);
180 else
181   qualify_domain = US"";  /* Don't want NULL */
182
183 s = US getenv("QUEUE_DEPTH");
184 if (s && (x = Uatoi(s)) != 0) queue_depth = x;
185
186 if ((s = US getenv("QUEUE_FONT")))
187   queue_font = string_copy(s);
188
189 s = US getenv("QUEUE_INTERVAL");
190 if (s && (x = Uatoi(s)) != 0) queue_update = x;
191
192 s = US getenv("QUEUE_MAX_ADDRESSES");
193 if (s && (x = Uatoi(s)) != 0) queue_max_addresses = x;
194
195 s = US getenv("QUEUE_WIDTH");
196 if (s && (x = Uatoi(s)) != 0) queue_width = x;
197
198 if ((s = US getenv("SPOOL_DIRECTORY")))
199   spool_directory = string_copy(s);
200
201 s = US getenv("START_SMALL");
202 if (s && Ustrcmp(s, "yes") == 0) start_small = 1;
203
204 s = US getenv("TEXT_DEPTH");
205 if (s && (x = Uatoi(s)) != 0) text_depth = x;
206
207 if ((s = US getenv("WINDOW_TITLE")))
208   window_title = string_copy(s);
209
210 /* Deal with stripchart configuration. First see if we are monitoring
211 the size of a partition, then deal with log stripcharts in a separate
212 function */
213
214 s = US getenv("SIZE_STRIPCHART");
215 if (s && *s)
216   {
217   stripchart_number++;
218   stripchart_varstart++;
219   size_stripchart = string_copy(s);
220   s = US getenv("SIZE_STRIPCHART_NAME");
221   if (s != NULL && *s != 0) size_stripchart_name = string_copy(s);
222   }
223
224 if ((s = US getenv("LOG_STRIPCHARTS")))
225   decode_stripchart_config(s);
226
227 s = US getenv("STRIPCHART_INTERVAL");
228 if (s && (x = Uatoi(s)) != 0) stripchart_update = x;
229
230 s = US getenv("QUEUE_STRIPCHART_NAME");
231 queue_stripchart_name = s ? string_copy(s) : US"queue";
232
233 /* Compile the regex for matching yyyy-mm-dd at the start of a string. */
234
235 yyyymmdd_regex = pcre2_compile((PCRE2_SPTR)"^\\d{4}-\\d\\d-\\d\\d\\s",
236   PCRE2_ZERO_TERMINATED, PCRE_COPT, &x, &erroroffset, NULL);
237 }
238
239 /* End of em_init.c */