static int _ext_enotify_option_check (void *context, struct sieve_ast_argument *arg) { struct _ext_enotify_option_check_context *optn_context = (struct _ext_enotify_option_check_context *) context; struct sieve_validator *valdtr = optn_context->valdtr; const struct sieve_enotify_method *method = optn_context->method; struct sieve_enotify_env nenv; const char *option = sieve_ast_argument_strc(arg); const char *opt_name = NULL, *opt_value = NULL; bool check = TRUE; int result = 1; /* Compose log structure */ memset(&nenv, 0, sizeof(nenv)); nenv.svinst = optn_context->svinst; nenv.method = method; nenv.ehandler = sieve_prefix_ehandler_create (sieve_validator_error_handler(valdtr), sieve_error_script_location (sieve_validator_script(valdtr), arg->source_line), "notify command"); /* Parse option */ if ( !sieve_argument_is_string_literal(arg) ) { /* Variable string: partial option parse * * If the string item is not a string literal, it cannot be validated fully * at compile time. We can however check whether the '=' is in the string * specification and whether the part before the '=' is a valid option name. * In that case, the method option check function is called with the value * parameter equal to NULL, meaning that it should only check the validity * of the option itself and not the assigned value. */ if ( !ext_enotify_option_parse(NULL, option, TRUE, &opt_name, &opt_value) ) check = FALSE; } else { /* Literal string: full option parse */ if ( !ext_enotify_option_parse (&nenv, option, FALSE, &opt_name, &opt_value) ) result = -1; } /* Call method's option check function */ if ( result > 0 && check && method->def != NULL && method->def->compile_check_option != NULL ) { result = ( method->def->compile_check_option (&nenv, opt_name, opt_value) ? 1 : -1 ); } sieve_error_handler_unref(&nenv.ehandler); return result; }
void sieve_generator_critical (struct sieve_generator *gentr, unsigned int source_line, const char *fmt, ...) { va_list args; va_start(args, fmt); sieve_vwarning(gentr->ehandler, sieve_error_script_location(gentr->genenv.script, source_line), fmt, args); va_end(args); }
bool ext_enotify_compile_check_arguments (struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *uri_arg, struct sieve_ast_argument *msg_arg, struct sieve_ast_argument *from_arg, struct sieve_ast_argument *options_arg) { const struct sieve_extension *this_ext = cmd->ext; struct sieve_instance *svinst = this_ext->svinst; const char *uri = sieve_ast_argument_strc(uri_arg); const char *scheme; const struct sieve_enotify_method *method; struct sieve_enotify_env nenv; bool result = TRUE; /* If the uri string is not a constant literal, we cannot determine which * method is used, so we bail out successfully and defer checking to runtime. */ if ( !sieve_argument_is_string_literal(uri_arg) ) return TRUE; /* Parse scheme part of URI */ if ( (scheme=ext_enotify_uri_scheme_parse(&uri)) == NULL ) { sieve_argument_validate_error(valdtr, uri_arg, "notify command: invalid scheme part for method URI '%s'", str_sanitize(sieve_ast_argument_strc(uri_arg), 80)); return FALSE; } /* Find used method with the parsed scheme identifier */ if ( (method=ext_enotify_method_find(this_ext, scheme)) == NULL ) { sieve_argument_validate_error(valdtr, uri_arg, "notify command: invalid method '%s'", scheme); return FALSE; } if ( method->def == NULL ) return TRUE; /* Compose log structure */ memset(&nenv, 0, sizeof(nenv)); nenv.svinst = svinst; nenv.method = method; /* Check URI itself */ if ( result && method->def->compile_check_uri != NULL ) { /* Set log location to location of URI argument */ nenv.ehandler = sieve_prefix_ehandler_create (sieve_validator_error_handler(valdtr), sieve_error_script_location (sieve_validator_script(valdtr), uri_arg->source_line), "notify command"); /* Execute method check function */ result = method->def->compile_check_uri (&nenv, sieve_ast_argument_strc(uri_arg), uri); } /* Check :message argument */ if ( result && msg_arg != NULL && sieve_argument_is_string_literal(msg_arg) && method->def->compile_check_message != NULL ) { /* Set log location to location of :message argument */ sieve_error_handler_unref(&nenv.ehandler); nenv.ehandler = sieve_prefix_ehandler_create (sieve_validator_error_handler(valdtr), sieve_error_script_location (sieve_validator_script(valdtr), msg_arg->source_line), "notify command"); /* Execute method check function */ result = method->def->compile_check_message (&nenv, sieve_ast_argument_str(msg_arg)); } /* Check :from argument */ if ( result && from_arg != NULL && sieve_argument_is_string_literal(from_arg) && method->def->compile_check_from != NULL ) { /* Set log location to location of :from argument */ sieve_error_handler_unref(&nenv.ehandler); nenv.ehandler = sieve_prefix_ehandler_create (sieve_validator_error_handler(valdtr), sieve_error_script_location (sieve_validator_script(valdtr), from_arg->source_line), "notify command"); /* Execute method check function */ result = method->def->compile_check_from (&nenv, sieve_ast_argument_str(from_arg)); } sieve_error_handler_unref(&nenv.ehandler); /* Check :options argument */ if ( result && options_arg != NULL ) { struct sieve_ast_argument *option = options_arg; struct _ext_enotify_option_check_context optn_context = { svinst, valdtr, method }; /* Parse and check options */ result = ( sieve_ast_stringlist_map (&option, (void *) &optn_context, _ext_enotify_option_check) > 0 ); /* Discard argument if options are not accepted by method */ if ( result && method->def->compile_check_option == NULL ) { sieve_argument_validate_warning(valdtr, options_arg, "notify command: method '%s' accepts no options", scheme); (void)sieve_ast_arguments_detach(options_arg,1); } } return result; }