* HAPROXY_MASTER_CLI: In master-worker mode, listeners addresses of the master
CLI, separated by semicolons.
+In addition, some pseudo-variables are internally resolved and may be used as
+regular variables. Pseudo-variables always start with a dot ('.'), and are the
+only ones where the dot is permitted. The current list of pseudo-variables is:
+
+* .FILE: the name of the configuration file currently being parsed.
+
+* .LINE: the line number of the configuration file currently being parsed,
+ starting at one.
+
+* .SECTION: the name of the section currently being parsed, or its type if the
+ section doesn't have a name (e.g. "global"), or an empty string before the
+ first section.
+
+These variables are resolved at the location where they are parsed. For example
+if a ".LINE" variable is used in a "log-format" directive located in a defaults
+section, its line number will be resolved before parsing and compiling the
+"log-format" directive, so this same line number will be reused by subsequent
+proxies.
+
+This way it is possible to emit information to help locate a rule in variables,
+logs, error statuses, health checks, header values, or even to use line numbers
+to name some config objects like servers for example.
+
See also "external-check command" for other variables.
*/
char *var_name;
char save_char;
- char *value;
+ const char *value;
in++;
if (*in == '{')
brace = in++;
- if (!isalpha((unsigned char)*in) && *in != '_') {
+ if (!isalpha((unsigned char)*in) && *in != '_' && *in != '.') {
/* unacceptable character in variable name */
err |= PARSE_ERR_VARNAME;
if (errptr)
}
var_name = in;
+ if (*in == '.')
+ in++;
while (isalnum((unsigned char)*in) || *in == '_')
in++;
save_char = *in;
*in = '\0';
- value = getenv(var_name);
+ if (unlikely(*var_name == '.')) {
+ /* internal pseudo-variables */
+ if (strcmp(var_name, ".LINE") == 0)
+ value = ultoa(global.cfg_curr_line);
+ else if (strcmp(var_name, ".FILE") == 0)
+ value = global.cfg_curr_file;
+ else if (strcmp(var_name, ".SECTION") == 0)
+ value = global.cfg_curr_section;
+ else {
+ /* unsupported internal variable name */
+ err |= PARSE_ERR_VARNAME;
+ if (errptr)
+ *errptr = var_name;
+ goto leave;
+ }
+ } else {
+ value = getenv(var_name);
+ }
*in = save_char;
/* support for '[*]' sequence to force word expansion,