1/* $NetBSD$ */ 2 3/*++ 4/* NAME 5/* postconf_match 3 6/* SUMMARY 7/* pattern-matching support 8/* SYNOPSIS 9/* #include <postconf.h> 10/* 11/* int pcf_parse_field_pattern(field_expr) 12/* char *field_expr; 13/* 14/* const char *pcf_str_field_pattern(field_pattern) 15/* int field_pattern; 16/* 17/* int pcf_is_magic_field_pattern(field_pattern) 18/* int field_pattern; 19/* 20/* ARGV *pcf_parse_service_pattern(service_expr, min_expr, max_expr) 21/* const char *service_expr; 22/* int min_expr; 23/* int max_expr; 24/* 25/* int PCF_IS_MAGIC_SERVICE_PATTERN(service_pattern) 26/* const ARGV *service_pattern; 27/* 28/* int PCF_MATCH_SERVICE_PATTERN(service_pattern, service_name, 29/* service_type) 30/* const ARGV *service_pattern; 31/* const char *service_name; 32/* const char *service_type; 33/* 34/* const char *pcf_str_field_pattern(field_pattern) 35/* int field_pattern; 36/* 37/* int PCF_IS_MAGIC_PARAM_PATTERN(param_pattern) 38/* const char *param_pattern; 39/* 40/* int PCF_MATCH_PARAM_PATTERN(param_pattern, param_name) 41/* const char *param_pattern; 42/* const char *param_name; 43/* DESCRIPTION 44/* pcf_parse_service_pattern() takes an expression and splits 45/* it up on '/' into an array of sub-expressions, This function 46/* returns null if the input does fewer than "min" or more 47/* than "max" sub-expressions. 48/* 49/* PCF_IS_MAGIC_SERVICE_PATTERN() returns non-zero if any of 50/* the service name or service type sub-expressions contains 51/* a matching operator (as opposed to string literals that 52/* only match themselves). This is an unsafe macro that evaluates 53/* its arguments more than once. 54/* 55/* PCF_MATCH_SERVICE_PATTERN() matches a service name and type 56/* from master.cf against the parsed pattern. This is an unsafe 57/* macro that evaluates its arguments more than once. 58/* 59/* pcf_parse_field_pattern() converts a field sub-expression, 60/* and returns the conversion result. 61/* 62/* pcf_str_field_pattern() converts a result from 63/* pcf_parse_field_pattern() into string form. 64/* 65/* pcf_is_magic_field_pattern() returns non-zero if the field 66/* pattern sub-expression contained a matching operator (as 67/* opposed to a string literal that only matches itself). 68/* 69/* PCF_IS_MAGIC_PARAM_PATTERN() returns non-zero if the parameter 70/* sub-expression contains a matching operator (as opposed to 71/* a string literal that only matches itself). This is an 72/* unsafe macro that evaluates its arguments more than once. 73/* 74/* PCF_MATCH_PARAM_PATTERN() matches a parameter name from 75/* master.cf against the parsed pattern. This is an unsafe 76/* macro that evaluates its arguments more than once. 77/* 78/* Arguments 79/* .IP field_expr 80/* A field expression. 81/* .IP service_expr 82/* This argument is split on '/' into its constituent 83/* sub-expressions. 84/* .IP min_expr 85/* The minimum number of sub-expressions in service_expr. 86/* .IP max_expr 87/* The maximum number of sub-expressions in service_expr. 88/* .IP service_name 89/* Service name from master.cf. 90/* .IP service_type 91/* Service type from master.cf. 92/* .IP param_pattern 93/* A parameter name expression. 94/* DIAGNOSTICS 95/* Fatal errors: invalid syntax. 96/* LICENSE 97/* .ad 98/* .fi 99/* The Secure Mailer license must be distributed with this software. 100/* AUTHOR(S) 101/* Wietse Venema 102/* IBM T.J. Watson Research 103/* P.O. Box 704 104/* Yorktown Heights, NY 10598, USA 105/*--*/ 106 107/* System library. */ 108 109#include <sys_defs.h> 110#include <string.h> 111 112/* Utility library. */ 113 114#include <msg.h> 115#include <mymalloc.h> 116#include <vstring.h> 117 118/* Global library. */ 119 120#include <split_at.h> 121 122/* Application-specific. */ 123 124#include <postconf.h> 125 126 /* 127 * Conversion table. Each PCF_MASTER_NAME_XXX name entry must be stored at 128 * table offset PCF_MASTER_FLD_XXX. So don't mess it up. 129 */ 130NAME_CODE pcf_field_name_offset[] = { 131 PCF_MASTER_NAME_SERVICE, PCF_MASTER_FLD_SERVICE, 132 PCF_MASTER_NAME_TYPE, PCF_MASTER_FLD_TYPE, 133 PCF_MASTER_NAME_PRIVATE, PCF_MASTER_FLD_PRIVATE, 134 PCF_MASTER_NAME_UNPRIV, PCF_MASTER_FLD_UNPRIV, 135 PCF_MASTER_NAME_CHROOT, PCF_MASTER_FLD_CHROOT, 136 PCF_MASTER_NAME_WAKEUP, PCF_MASTER_FLD_WAKEUP, 137 PCF_MASTER_NAME_MAXPROC, PCF_MASTER_FLD_MAXPROC, 138 PCF_MASTER_NAME_CMD, PCF_MASTER_FLD_CMD, 139 "*", PCF_MASTER_FLD_WILDC, 140 0, PCF_MASTER_FLD_NONE, 141}; 142 143/* pcf_parse_field_pattern - parse service attribute pattern */ 144 145int pcf_parse_field_pattern(const char *field_name) 146{ 147 int field_pattern; 148 149 if ((field_pattern = name_code(pcf_field_name_offset, 150 NAME_CODE_FLAG_STRICT_CASE, 151 field_name)) == PCF_MASTER_FLD_NONE) 152 msg_fatal("invalid service attribute name: \"%s\"", field_name); 153 return (field_pattern); 154} 155 156/* pcf_parse_service_pattern - parse service pattern */ 157 158ARGV *pcf_parse_service_pattern(const char *pattern, int min_expr, int max_expr) 159{ 160 ARGV *argv; 161 char **cpp; 162 163 /* 164 * Work around argv_split() lameness. 165 */ 166 if (*pattern == '/') 167 return (0); 168 argv = argv_split(pattern, PCF_NAMESP_SEP_STR); 169 if (argv->argc < min_expr || argv->argc > max_expr) { 170 argv_free(argv); 171 return (0); 172 } 173 174 /* 175 * Allow '*' only all by itself. 176 */ 177 for (cpp = argv->argv; *cpp; cpp++) { 178 if (!PCF_MATCH_ANY(*cpp) && strchr(*cpp, PCF_MATCH_WILDC_STR[0]) != 0) { 179 argv_free(argv); 180 return (0); 181 } 182 } 183 184 /* 185 * Provide defaults for missing fields. 186 */ 187 while (argv->argc < max_expr) 188 argv_add(argv, PCF_MATCH_WILDC_STR, ARGV_END); 189 return (argv); 190} 191