-: 0:Source:modperl_options.c -: 0:Object:modperl_options.bb -: 1:/* Copyright 2000-2004 The Apache Software Foundation -: 2: * -: 3: * Licensed under the Apache License, Version 2.0 (the "License"); -: 4: * you may not use this file except in compliance with the License. -: 5: * You may obtain a copy of the License at -: 6: * -: 7: * http://www.apache.org/licenses/LICENSE-2.0 -: 8: * -: 9: * Unless required by applicable law or agreed to in writing, software -: 10: * distributed under the License is distributed on an "AS IS" BASIS, -: 11: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -: 12: * See the License for the specific language governing permissions and -: 13: * limitations under the License. -: 14: */ -: 15: -: 16:#include "mod_perl.h" -: 17: -: 18:/* re-use the ->unset field to determine options type */ -: 19:#define MpOptionsType(o) (o)->unset -: 20:#define MpOptionsTypeDir(o) MpOptionsType(o) == MpDir_f_UNSET -: 21:#define MpOptionsTypeSrv(o) MpOptionsType(o) == MpSrv_f_UNSET -: 22:#define MpOptionsTypeDir_set(o) MpOptionsType(o) = MpDir_f_UNSET -: 23:#define MpOptionsTypeSrv_set(o) MpOptionsType(o) = MpSrv_f_UNSET -: 24:#define MP_OPTIONS_TYPE_DIR MpDir_f_UNSET -: 25:#define MP_OPTIONS_TYPE_SRV MpSrv_f_UNSET -: 26: -: 27:static modperl_opts_t flags_lookup(modperl_options_t *o, -: 28: const char *str) 228: 29:{ 228: 30: switch (MpOptionsType(o)) { -: 31: case MP_OPTIONS_TYPE_SRV: 48: 32: return modperl_flags_lookup_srv(str); -: 33: case MP_OPTIONS_TYPE_DIR: 180: 34: return modperl_flags_lookup_dir(str); -: 35: default: #####: 36: return '\0'; -: 37: }; -: 38:} -: 39: -: 40:static const char *type_lookup(modperl_options_t *o) 4: 41:{ 4: 42: switch (MpOptionsType(o)) { -: 43: case MP_OPTIONS_TYPE_SRV: 4: 44: return "server"; -: 45: case MP_OPTIONS_TYPE_DIR: #####: 46: return "directory"; -: 47: default: #####: 48: return "unknown"; -: 49: }; -: 50:} -: 51: -: 52:modperl_options_t *modperl_options_new(apr_pool_t *p, int type) 2984: 53:{ 2984: 54: modperl_options_t *options = 5968: 55: (modperl_options_t *)apr_pcalloc(p, sizeof(*options)); -: 56: 2984: 57: options->opts = options->unset = -: 58: (type == MpSrvType ? MpSrv_f_UNSET : MpDir_f_UNSET); -: 59: 2984: 60: return options; -: 61:} -: 62: -: 63:const char *modperl_options_set(apr_pool_t *p, modperl_options_t *o, -: 64: const char *str) 228: 65:{ 228: 66: modperl_opts_t opt; 228: 67: char action = '\0'; 228: 68: const char *error = NULL; -: 69: 228: 70: if (*str == '+' || *str == '-') { 228: 71: action = *(str++); -: 72: } -: 73: 228: 74: if (!(opt = flags_lookup(o, str))) { 4: 75: error = apr_pstrcat(p, "Invalid per-", type_lookup(o), -: 76: " PerlOption: ", str, NULL); -: 77: 4: 78: if (MpOptionsTypeDir(o)) { #####: 79: modperl_options_t dummy; #####: 80: MpOptionsTypeSrv_set(&dummy); -: 81: #####: 82: if (flags_lookup(&dummy, str)) { #####: 83: error = apr_pstrcat(p, error, -: 84: " (only allowed per-server)", -: 85: NULL); -: 86: } -: 87: } -: 88: 4: 89: return error; -: 90: } -: 91:#ifndef USE_ITHREADS -: 92: else if (MpOptionsTypeSrv(o)) { -: 93: if (MpSrvOPT_ITHREAD_ONLY(opt)) { -: 94: return apr_pstrcat(p, "PerlOption `", str, -: 95: "' requires an ithreads enabled Perl", NULL); -: 96: } -: 97: } -: 98:#endif -: 99: 224: 100: o->opts_seen |= opt; -: 101: 224: 102: if (action == '-') { 68: 103: o->opts_remove |= opt; 68: 104: o->opts_add &= ~opt; 68: 105: o->opts &= ~opt; -: 106: } 156: 107: else if (action == '+') { 156: 108: o->opts_add |= opt; 156: 109: o->opts_remove &= ~opt; 156: 110: o->opts |= opt; -: 111: } -: 112: else { #####: 113: o->opts |= opt; -: 114: } -: 115: 224: 116: return NULL; -: 117:} -: 118: -: 119:modperl_options_t *modperl_options_merge(apr_pool_t *p, -: 120: modperl_options_t *base, -: 121: modperl_options_t *add) 1002: 122:{ 1002: 123: modperl_options_t *conf = modperl_options_new(p, 0); 1002: 124: memcpy((char *)conf, (const char *)base, sizeof(*base)); -: 125: 1002: 126: if (add->opts & add->unset) { -: 127: /* there was no explicit setting of add->opts, so we merge -: 128: * preserve the invariant (opts_add & opts_remove) == 0 -: 129: */ 1002: 130: conf->opts_add = -: 131: (conf->opts_add & ~add->opts_remove) | add->opts_add; 1002: 132: conf->opts_remove = -: 133: (conf->opts_remove & ~add->opts_add) | add->opts_remove; 1002: 134: conf->opts = -: 135: (conf->opts & ~conf->opts_remove) | conf->opts_add; -: 136: } -: 137: else { -: 138: /* otherwise we just copy, because an explicit opts setting -: 139: * overrides all earlier +/- modifiers -: 140: */ #####: 141: conf->opts = add->opts; #####: 142: conf->opts_add = add->opts_add; #####: 143: conf->opts_remove = add->opts_remove; -: 144: } -: 145: 1002: 146: conf->opts_seen |= add->opts_seen; -: 147: 1002: 148: return conf; -: 149:}