bool sieve_extprogram_command_validate (struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; struct sieve_ast_argument *stritem; struct _arg_validate_context actx; string_t *program_name; if ( arg == NULL ) { sieve_command_validate_error(valdtr, cmd, "the %s %s expects at least one positional argument, but none was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } /* <program-name: string> argument */ if ( !sieve_validate_positional_argument (valdtr, cmd, arg, "program-name", 1, SAAT_STRING) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, cmd, arg, FALSE) ) return FALSE; /* Variables are not allowed */ if ( !sieve_argument_is_string_literal(arg) ) { sieve_argument_validate_error(valdtr, arg, "the %s %s requires a constant string " "for its program-name argument", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } /* Check program name */ program_name = sieve_ast_argument_str(arg); if ( !sieve_extprogram_name_is_valid(program_name) ) { sieve_argument_validate_error(valdtr, arg, "%s %s: invalid program name '%s'", sieve_command_identifier(cmd), sieve_command_type_name(cmd), str_sanitize(str_c(program_name), 80)); return FALSE; } /* Optional <arguments: string-list> argument */ arg = sieve_ast_argument_next(arg); if ( arg == NULL ) return TRUE; if ( !sieve_validate_positional_argument (valdtr, cmd, arg, "arguments", 2, SAAT_STRING_LIST) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, cmd, arg, FALSE) ) return FALSE; /* Check arguments */ actx.valdtr = valdtr; actx.cmd = cmd; stritem = arg; if ( sieve_ast_stringlist_map (&stritem, (void *)&actx, _arg_validate) <= 0 ) { return FALSE; } if ( sieve_ast_argument_next(arg) != NULL ) { sieve_command_validate_error(valdtr, cmd, "the %s %s expects at most two positional arguments, but more were found", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } return TRUE; }
int mailbox_list_delete_mailbox_nonrecursive(struct mailbox_list *list, const char *name, const char *path, bool rmdir_path) { DIR *dir; struct dirent *d; string_t *full_path; unsigned int dir_len; bool mailbox_dir, unlinked_something = FALSE; if (mailbox_list_check_root_delete(list, name, path) < 0) return -1; dir = opendir(path); if (dir == NULL) { if (errno == ENOENT) { mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND, T_MAILBOX_LIST_ERR_NOT_FOUND(list, name)); } else { if (!mailbox_list_set_error_from_errno(list)) { mailbox_list_set_critical(list, "opendir(%s) failed: %m", path); } } return -1; } full_path = t_str_new(256); str_append(full_path, path); str_append_c(full_path, '/'); dir_len = str_len(full_path); for (errno = 0; (d = readdir(dir)) != NULL; errno = 0) { if (d->d_name[0] == '.') { /* skip . and .. */ if (d->d_name[1] == '\0') continue; if (d->d_name[1] == '.' && d->d_name[2] == '\0') continue; } mailbox_dir = list->v.is_internal_name != NULL && list->v.is_internal_name(list, d->d_name); str_truncate(full_path, dir_len); str_append(full_path, d->d_name); if (mailbox_dir) { if (mailbox_list_delete_trash(str_c(full_path)) < 0) { mailbox_list_set_critical(list, "unlink_directory(%s) failed: %m", str_c(full_path)); } else { unlinked_something = TRUE; } continue; } /* trying to unlink() a directory gives either EPERM or EISDIR (non-POSIX). it doesn't really work anywhere in practise, so don't bother stat()ing the file first */ if (unlink(str_c(full_path)) == 0) unlinked_something = TRUE; else if (errno != ENOENT && !UNLINK_EISDIR(errno)) { mailbox_list_set_critical(list, "unlink_directory(%s) failed: %m", str_c(full_path)); } } if (errno != 0) mailbox_list_set_critical(list, "readdir(%s) failed: %m", path); if (closedir(dir) < 0) { mailbox_list_set_critical(list, "closedir(%s) failed: %m", path); } if (rmdir_path) { if (rmdir(path) == 0) unlinked_something = TRUE; else if (errno != ENOENT && errno != ENOTEMPTY && errno != EEXIST) { mailbox_list_set_critical(list, "rmdir(%s) failed: %m", path); return -1; } } if (!unlinked_something) { mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Mailbox has children, can't delete it"); return -1; } return 0; }
static void test_gen_and_get_info_rsa_pem(void) { test_begin("test_gen_and_get_info_rsa_pem"); const char *error = NULL; bool ret = FALSE; struct dcrypt_keypair pair; string_t* buf = str_new(default_pool, 4096); ret = dcrypt_keypair_generate(&pair, DCRYPT_KEY_RSA, 1024, NULL, NULL); test_assert(ret == TRUE); /* test public key */ enum dcrypt_key_format format; enum dcrypt_key_version version; enum dcrypt_key_kind kind; enum dcrypt_key_encryption_type encryption_type; const char *encryption_key_hash; const char *key_hash; ret = dcrypt_key_store_public(pair.pub, DCRYPT_FORMAT_PEM, buf, &error); test_assert(ret == TRUE); ret = dcrypt_key_string_get_info(str_c(buf), &format, &version, &kind, &encryption_type, &encryption_key_hash, &key_hash, &error); test_assert(ret == TRUE); test_assert(format == DCRYPT_FORMAT_PEM); test_assert(version == DCRYPT_KEY_VERSION_NA); test_assert(kind == DCRYPT_KEY_KIND_PUBLIC); test_assert(encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_NONE); test_assert(encryption_key_hash == NULL); test_assert(key_hash == NULL); /* test private key */ buffer_set_used_size(buf, 0); ret = dcrypt_key_store_private(pair.priv, DCRYPT_FORMAT_PEM, NULL, buf, NULL, NULL, &error); test_assert(ret == TRUE); ret = dcrypt_key_string_get_info(str_c(buf), &format, &version, &kind, &encryption_type, &encryption_key_hash, &key_hash, &error); test_assert(ret == TRUE); test_assert(format == DCRYPT_FORMAT_PEM); test_assert(version == DCRYPT_KEY_VERSION_NA); test_assert(kind == DCRYPT_KEY_KIND_PRIVATE); test_assert(encryption_type == DCRYPT_KEY_ENCRYPTION_TYPE_NONE); test_assert(encryption_key_hash == NULL); test_assert(key_hash == NULL); dcrypt_keypair_free(&pair); buffer_free(&buf); test_end(); }
static void service_dup_fds(struct service *service) { struct service_listener *const *listeners; ARRAY_TYPE(dup2) dups; string_t *listener_names; int fd = MASTER_LISTEN_FD_FIRST; unsigned int i, count, socket_listener_count, ssl_socket_count; /* stdin/stdout is already redirected to /dev/null. Other master fds should have been opened with fd_close_on_exec() so we don't have to worry about them. because the destination fd might be another one's source fd we have to be careful not to overwrite anything. dup() the fd when needed */ socket_listener_count = 0; listeners = array_get(&service->listeners, &count); t_array_init(&dups, count + 10); listener_names = t_str_new(256); switch (service->type) { case SERVICE_TYPE_LOG: i_assert(fd == MASTER_LISTEN_FD_FIRST); services_log_dup2(&dups, service->list, fd, &socket_listener_count); fd += socket_listener_count; break; case SERVICE_TYPE_ANVIL: dup2_append(&dups, service_anvil_global->log_fdpass_fd[0], MASTER_ANVIL_LOG_FDPASS_FD); /* nonblocking anvil fd must be the first one. anvil treats it as the master's fd */ dup2_append(&dups, service_anvil_global->nonblocking_fd[0], fd++); dup2_append(&dups, service_anvil_global->blocking_fd[0], fd++); socket_listener_count += 2; break; default: break; } /* anvil/log fds have no names */ for (i = MASTER_LISTEN_FD_FIRST; i < (unsigned int)fd; i++) str_append_c(listener_names, '\t'); /* first add non-ssl listeners */ for (i = 0; i < count; i++) { if (listeners[i]->fd != -1 && (listeners[i]->type != SERVICE_LISTENER_INET || !listeners[i]->set.inetset.set->ssl)) { str_append_tabescaped(listener_names, listeners[i]->name); str_append_c(listener_names, '\t'); dup2_append(&dups, listeners[i]->fd, fd++); socket_listener_count++; } } /* then ssl-listeners */ ssl_socket_count = 0; for (i = 0; i < count; i++) { if (listeners[i]->fd != -1 && listeners[i]->type == SERVICE_LISTENER_INET && listeners[i]->set.inetset.set->ssl) { str_append_tabescaped(listener_names, listeners[i]->name); str_append_c(listener_names, '\t'); dup2_append(&dups, listeners[i]->fd, fd++); socket_listener_count++; ssl_socket_count++; } } if (service->login_notify_fd != -1) { dup2_append(&dups, service->login_notify_fd, MASTER_LOGIN_NOTIFY_FD); } switch (service->type) { case SERVICE_TYPE_LOG: case SERVICE_TYPE_ANVIL: case SERVICE_TYPE_CONFIG: dup2_append(&dups, null_fd, MASTER_ANVIL_FD); break; case SERVICE_TYPE_UNKNOWN: case SERVICE_TYPE_LOGIN: case SERVICE_TYPE_STARTUP: dup2_append(&dups, service_anvil_global->blocking_fd[1], MASTER_ANVIL_FD); break; } dup2_append(&dups, service->status_fd[1], MASTER_STATUS_FD); if (service->type != SERVICE_TYPE_ANVIL) { dup2_append(&dups, service->list->master_dead_pipe_fd[1], MASTER_DEAD_FD); } else { dup2_append(&dups, global_master_dead_pipe_fd[1], MASTER_DEAD_FD); } if (service->type == SERVICE_TYPE_LOG) { /* keep stderr as-is. this is especially important when log_path=/dev/stderr, but might be helpful even in other situations for logging startup errors */ } else { /* set log file to stderr. dup2() here immediately so that we can set up logging to it without causing any log messages to be lost. */ i_assert(service->log_fd[1] != -1); env_put("LOG_SERVICE=1"); if (dup2(service->log_fd[1], STDERR_FILENO) < 0) i_fatal("dup2(log fd) failed: %m"); i_set_failure_internal(); } /* make sure we don't leak syslog fd. try to do it as late as possible, but also before dup2()s in case syslog fd is one of them. */ closelog(); if (dup2_array(&dups) < 0) i_fatal("service(%s): dup2s failed", service->set->name); i_assert(fd == MASTER_LISTEN_FD_FIRST + (int)socket_listener_count); env_put(t_strdup_printf("SOCKET_COUNT=%d", socket_listener_count)); env_put(t_strdup_printf("SSL_SOCKET_COUNT=%d", ssl_socket_count)); env_put(t_strdup_printf("SOCKET_NAMES=%s", str_c(listener_names))); }
static void test_message_address(void) { static const char *input[] = { "user@domain", NULL, "<user@domain>", "user@domain", "foo bar <user@domain>", NULL, "\"foo bar\" <user@domain>", "foo bar <user@domain>", "<@route:user@domain>", NULL, "<@route@route2:user@domain>", "<@route,@route2:user@domain>", "hello <@route ,@route2:user@domain>", "hello <@route,@route2:user@domain>", "user (hello)", NULL, "hello <user>", NULL, "@domain", NULL }; static struct message_address group_prefix = { NULL, NULL, NULL, "group", NULL, FALSE }; static struct message_address group_suffix = { NULL, NULL, NULL, NULL, NULL, FALSE }; static struct message_address output[] = { { NULL, NULL, NULL, "user", "domain", FALSE }, { NULL, NULL, NULL, "user", "domain", FALSE }, { NULL, "foo bar", NULL, "user", "domain", FALSE }, { NULL, "foo bar", NULL, "user", "domain", FALSE }, { NULL, NULL, "@route", "user", "domain", FALSE }, { NULL, NULL, "@route,@route2", "user", "domain", FALSE }, { NULL, "hello", "@route,@route2", "user", "domain", FALSE }, { NULL, "hello", NULL, "user", "", TRUE }, { NULL, "hello", NULL, "user", "", TRUE }, { NULL, NULL, NULL, "", "domain", TRUE } }; struct message_address *addr; string_t *str, *group; const char *wanted_string; unsigned int i; i_assert(N_ELEMENTS(input) == N_ELEMENTS(output)*2); test_begin("message address parsing"); str = t_str_new(128); group = t_str_new(256); str_append(group, "group: "); for (i = 0; i < N_ELEMENTS(output); i++) { addr = message_address_parse(pool_datastack_create(), (const unsigned char *)input[i*2], strlen(input[i*2]), UINT_MAX, FALSE); test_assert(addr != NULL && addr->next == NULL && cmp_addr(addr, &output[i])); if (!output[i].invalid_syntax) { str_truncate(str, 0); message_address_write(str, addr); wanted_string = input[i*2+1] != NULL ? input[i*2+1] : input[i*2]; test_assert(strcmp(str_c(str), wanted_string) == 0); if (i != 0) { if ((i % 2) == 0) str_append(group, ","); else str_append(group, " , \n "); } str_append(group, input[i*2]); } } str_append_c(group, ';'); test_end(); test_begin("message address parsing with groups"); addr = message_address_parse(pool_datastack_create(), str_data(group), str_len(group), UINT_MAX, FALSE); test_assert(addr != NULL && cmp_addr(addr, &group_prefix)); addr = addr->next; for (i = 0; i < N_ELEMENTS(output) && addr != NULL; i++) { if (output[i].invalid_syntax) continue; test_assert(cmp_addr(addr, &output[i])); addr = addr->next; } test_assert(addr != NULL && addr->next == NULL && cmp_addr(addr, &group_suffix)); test_end(); test_begin("message address parsing with empty group"); str_truncate(group, 0); str_append(group, "group:;"); addr = message_address_parse(pool_datastack_create(), str_data(group), str_len(group), UINT_MAX, FALSE); test_assert(addr != NULL && cmp_addr(addr, &group_prefix)); addr = addr->next; test_assert(addr != NULL && addr->next == NULL && cmp_addr(addr, &group_suffix)); test_end(); }
static void mail_log_append_mail_message_real(struct mail_log_mail_txn_context *ctx, struct mail *mail, enum mail_log_event event, const char *desc) { struct mail_log_user *muser = MAIL_LOG_USER_CONTEXT(mail->box->storage->user); struct mail_log_message *msg; string_t *text; uoff_t size; msg = p_new(ctx->pool, struct mail_log_message, 1); text = t_str_new(128); str_append(text, desc); str_append(text, ": "); if ((muser->fields & MAIL_LOG_FIELD_BOX) != 0) { mail_log_append_mailbox_name(text, mail); str_append(text, ", "); } if ((muser->fields & MAIL_LOG_FIELD_UID) != 0) { if (event != MAIL_LOG_EVENT_SAVE && event != MAIL_LOG_EVENT_COPY) mail_log_append_uid(ctx, msg, text, mail->uid); else { /* with mbox mail->uid contains the uid, but handle this consistently with all mailbox formats */ mail_log_append_uid(ctx, msg, text, 0); } str_append(text, ", "); } if ((muser->fields & MAIL_LOG_FIELD_MSGID) != 0) { mail_log_append_mail_header(text, mail, "msgid", "Message-ID"); str_append(text, ", "); } if ((muser->fields & MAIL_LOG_FIELD_PSIZE) != 0) { if (mail_get_physical_size(mail, &size) == 0) str_printfa(text, "size=%"PRIuUOFF_T, size); else str_printfa(text, "size=error"); str_append(text, ", "); } if ((muser->fields & MAIL_LOG_FIELD_VSIZE) != 0) { if (mail_get_virtual_size(mail, &size) == 0) str_printfa(text, "vsize=%"PRIuUOFF_T, size); else str_printfa(text, "vsize=error"); str_append(text, ", "); } if ((muser->fields & MAIL_LOG_FIELD_FROM) != 0) { mail_log_append_mail_header(text, mail, "from", "From"); str_append(text, ", "); } if ((muser->fields & MAIL_LOG_FIELD_SUBJECT) != 0) { mail_log_append_mail_header(text, mail, "subject", "Subject"); str_append(text, ", "); } if ((muser->fields & MAIL_LOG_FIELD_FLAGS) != 0) { str_printfa(text, "flags=("); imap_write_flags(text, mail_get_flags(mail), mail_get_keywords(mail)); str_append(text, "), "); } str_truncate(text, str_len(text)-2); msg->event = event; msg->text = p_strdup(ctx->pool, str_c(text)); DLLIST2_APPEND(&ctx->messages, &ctx->messages_tail, msg); }
static void lmtp_address_translate(struct client *client, const char **address) { const char *transpos = client->lmtp_set->lmtp_address_translate; const char *p, *nextstr, *addrpos = *address; unsigned int len; string_t *username, *domain, *dest = NULL; if (*transpos == '\0') return; username = t_str_new(64); domain = t_str_new(64); /* check that string matches up to the first '%' */ p = strchr(transpos, '%'); if (p == NULL) len = strlen(transpos); else len = p-transpos; if (strncmp(transpos, addrpos, len) != 0) return; transpos += len; addrpos += len; while (*transpos != '\0') { switch (transpos[1]) { case 'n': case 'u': dest = username; break; case 'd': dest = domain; break; default: return; } transpos += 2; /* find where the next string starts */ if (*transpos == '\0') { str_append(dest, addrpos); break; } p = strchr(transpos, '%'); if (p == NULL) nextstr = transpos; else nextstr = t_strdup_until(transpos, p); p = strstr(addrpos, nextstr); if (p == NULL) return; str_append_n(dest, addrpos, p-addrpos); len = strlen(nextstr); transpos += len; addrpos = p + len; } str_append_c(username, '@'); if (domain != NULL) str_append_str(username, domain); *address = str_c(username); }
static int cmd_test_config_reload_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *ext; int opt_code = 0; string_t *extension = NULL; int ret; /* * Read operands */ /* Optional operands */ for (;;) { int opt; if ( (opt=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) return SIEVE_EXEC_BIN_CORRUPT; if ( opt == 0 ) break; switch ( opt_code ) { case OPT_EXTENSION: ret = sieve_opr_string_read(renv, address, "extension", &extension); break; default: sieve_runtime_trace_error(renv, "unknown optional operand"); ret = SIEVE_EXEC_BIN_CORRUPT; } if ( ret <= 0 ) return ret; } /* * Perform operation */ if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { sieve_runtime_trace(renv, 0, "testsuite: test_config_reload command"); sieve_runtime_trace_descend(renv); } if ( extension == NULL ) { testsuite_test_failf("test_config_reload: " ":extension argument is currently mandatory"); return SIEVE_EXEC_OK; } if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { sieve_runtime_trace(renv, 0, "reload configuration for extension `%s'", str_c(extension)); } ext = sieve_extension_get_by_name(renv->svinst, str_c(extension)); if ( ext == NULL ) { testsuite_test_failf("test_config_reload: " "unknown extension '%s'", str_c(extension)); return SIEVE_EXEC_OK; } sieve_extension_reload(ext); return SIEVE_EXEC_OK; }
static void dsync_fix_mailbox_name(struct mail_namespace *ns, string_t *vname_str, char alt_char) { const char *old_vname; char *vname, list_sep = mailbox_list_get_hierarchy_sep(ns->list); guid_128_t guid; unsigned int i, start_pos; vname = str_c_modifiable(vname_str); if (strncmp(vname, ns->prefix, ns->prefix_len) == 0) start_pos = ns->prefix_len; else start_pos = 0; /* replace control chars */ for (i = start_pos; vname[i] != '\0'; i++) { if ((unsigned char)vname[i] < ' ') vname[i] = alt_char; } /* make it valid UTF8 */ if (!uni_utf8_str_is_valid(vname)) { old_vname = t_strdup(vname + start_pos); str_truncate(vname_str, start_pos); if (uni_utf8_get_valid_data((const void *)old_vname, strlen(old_vname), vname_str)) i_unreached(); vname = str_c_modifiable(vname_str); } if (dsync_is_valid_name(ns, vname)) return; /* 1) change any real separators to alt separators (this wouldn't be necessary with listescape, but don't bother detecting it) */ if (list_sep != mail_namespace_get_sep(ns)) { for (i = start_pos; vname[i] != '\0'; i++) { if (vname[i] == list_sep) vname[i] = alt_char; } if (dsync_is_valid_name(ns, vname)) return; } /* 2) '/' characters aren't valid without listescape */ if (mail_namespace_get_sep(ns) != '/' && list_sep != '/') { for (i = start_pos; vname[i] != '\0'; i++) { if (vname[i] == '/') vname[i] = alt_char; } if (dsync_is_valid_name(ns, vname)) return; } /* 3) probably some reserved name (e.g. dbox-Mails) */ str_insert(vname_str, ns->prefix_len, "_"); if (dsync_is_valid_name(ns, str_c(vname_str))) return; /* 4) name is too long? just give up and generate a unique name */ guid_128_generate(guid); str_truncate(vname_str, 0); str_append(vname_str, ns->prefix); str_append(vname_str, guid_128_to_string(guid)); i_assert(dsync_is_valid_name(ns, str_c(vname_str))); }
static void mail_search_arg_to_cmdline(string_t *dest, const struct mail_search_arg *arg) { struct mail_search_arg new_arg; const char *error; if (arg->match_not) str_append(dest, "NOT "); switch (arg->type) { case SEARCH_OR: mail_search_subargs_to_cmdline(dest, arg->value.subargs, " OR "); return; case SEARCH_SUB: mail_search_subargs_to_cmdline(dest, arg->value.subargs, " "); return; case SEARCH_FLAGS: case SEARCH_KEYWORDS: { size_t pos = str_len(dest); new_arg = *arg; new_arg.match_not = FALSE; if (!mail_search_arg_to_imap(dest, &new_arg, &error)) i_unreached(); if (str_c(dest)[pos] == '(') { str_insert(dest, pos+1, " "); str_insert(dest, str_len(dest)-1, " "); } return; } case SEARCH_INTHREAD: str_append(dest, "INTHREAD "); imap_append_astring(dest, mail_thread_type_to_str(arg->value.thread_type)); str_append_c(dest, ' '); mail_search_subargs_to_cmdline(dest, arg->value.subargs, " "); break; case SEARCH_MAILBOX: case SEARCH_MAILBOX_GLOB: str_append(dest, "MAILBOX "); imap_append_astring(dest, arg->value.str); return; case SEARCH_MAILBOX_GUID: str_append(dest, "MAILBOX-GUID "); imap_append_astring(dest, arg->value.str); return; case SEARCH_ALL: case SEARCH_SEQSET: case SEARCH_UIDSET: case SEARCH_BEFORE: case SEARCH_ON: case SEARCH_SINCE: case SEARCH_SMALLER: case SEARCH_LARGER: case SEARCH_HEADER: case SEARCH_HEADER_ADDRESS: case SEARCH_HEADER_COMPRESS_LWSP: case SEARCH_BODY: case SEARCH_TEXT: case SEARCH_MODSEQ: case SEARCH_GUID: case SEARCH_REAL_UID: case SEARCH_MIMEPART: break; } new_arg = *arg; new_arg.match_not = FALSE; if (!mail_search_arg_to_imap(dest, &new_arg, &error)) i_panic("mail_search_args_to_cmdline(): Missing handler: %s", error); }
static int cmd_filter_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; unsigned int is_test = 0; struct sieve_stringlist *args_list = NULL; enum sieve_error error = SIEVE_ERROR_NONE; string_t *pname = NULL; const char *program_name = NULL; const char *const *args = NULL; struct istream *newmsg = NULL; struct sieve_extprogram *sprog; int ret; /* * Read operands */ /* The is_test flag */ if ( !sieve_binary_read_byte(renv->sblock, address, &is_test) ) { sieve_runtime_trace_error(renv, "invalid is_test flag"); return SIEVE_EXEC_BIN_CORRUPT; } /* Optional operands */ if ( sieve_action_opr_optional_read(renv, address, NULL, &ret, NULL) != 0 ) return ret; /* Fixed operands */ if ( (ret=sieve_extprogram_command_read_operands (renv, address, &pname, &args_list)) <= 0 ) return ret; program_name = str_c(pname); if ( args_list != NULL && sieve_stringlist_read_all(args_list, pool_datastack_create(), &args) < 0 ) { sieve_runtime_trace_error(renv, "failed to read args operand"); return args_list->exec_status; } /* * Perform operation */ /* Trace */ sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "filter action"); sieve_runtime_trace_descend(renv); sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "execute program `%s'", str_sanitize(program_name, 128)); sprog = sieve_extprogram_create (this_ext, renv->scriptenv, renv->msgdata, "filter", program_name, args, &error); if ( sprog != NULL ) { struct mail *mail = sieve_message_get_mail(renv->msgctx); if ( sieve_extprogram_set_input_mail(sprog, mail) < 0 ) { sieve_extprogram_destroy(&sprog); return sieve_runtime_mail_error(renv, mail, "filter action: failed to read input message"); } sieve_extprogram_set_output_seekable(sprog); ret = sieve_extprogram_run(sprog); } else { ret = -1; } if ( ret > 0 ) newmsg = sieve_extprogram_get_output_seekable(sprog); if ( sprog != NULL ) sieve_extprogram_destroy(&sprog); if ( ret > 0 && newmsg != NULL ) { sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "executed program successfully"); i_stream_set_name(newmsg, t_strdup_printf("filter %s output", program_name)); newmsg->blocking = TRUE; if ( (ret=sieve_message_substitute(renv->msgctx, newmsg)) >= 0 ) { sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "changed message"); } else { sieve_runtime_critical(renv, NULL, "filter action", "filter action: failed to substitute message"); } i_stream_unref(&newmsg); } else if ( ret < 0 ) { if ( error == SIEVE_ERROR_NOT_FOUND ) { sieve_runtime_error(renv, NULL, "filter action: program `%s' not found", str_sanitize(program_name, 80)); } else { sieve_extprogram_exec_error(renv->ehandler, sieve_runtime_get_full_command_location(renv), "filter action: failed to execute to program `%s'", str_sanitize(program_name, 80)); } } else { sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "filter action: program indicated false result"); } if ( is_test > 0 ) { sieve_interpreter_set_test_result(renv->interp, ( ret > 0 )); return SIEVE_EXEC_OK; } return ( ret >= 0 ? SIEVE_EXEC_OK : SIEVE_EXEC_FAILURE ); }
static void client_connected(struct master_service_connection *conn) { enum mail_storage_service_flags flags = MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS; string_t *instr, *keys; const char **args, *key, *value, *error, *version_line, *data_line; struct mail_storage_service_ctx *service_ctx; struct mail_storage_service_input input; struct mail_storage_service_user *user; char buf[1024]; unsigned int i, socket_count; int fd = -1; ssize_t ret; alarm(SCRIPT_LOGIN_READ_TIMEOUT_SECS); net_set_nonblock(conn->fd, FALSE); instr = t_str_new(1024); ret = fd_read(conn->fd, buf, sizeof(buf), &fd); while (ret > 0) { str_append_n(instr, buf, ret); if (buf[ret-1] == '\n' && strchr(str_c(instr), '\n')[1] != '\0') { str_truncate(instr, str_len(instr)-1); break; } ret = read(conn->fd, buf, sizeof(buf)); } version_line = str_c(instr); data_line = strchr(version_line, '\n'); if (data_line != NULL) version_line = t_strdup_until(version_line, data_line++); else version_line = NULL; if (ret > 0 || version_line != NULL) { if (version_line == NULL || !version_string_verify(version_line, "script-login", SCRIPT_LOGIN_PROTOCOL_VERSION_MAJOR)) { i_fatal("Client not compatible with this binary " "(connecting to wrong socket?)"); } } if (ret <= 0) { if (ret < 0) i_fatal("read() failed: %m"); else i_fatal("read() failed: disconnected"); } if (fd == -1) i_fatal("client fd not received"); /* put everything to environment */ env_clean(); keys = t_str_new(256); args = t_strsplit(data_line, "\t"); if (str_array_length(args) < 3) i_fatal("Missing input fields"); i = 0; memset(&input, 0, sizeof(input)); input.module = "mail"; /* need to get mail_uid, mail_gid */ input.service = "script-login"; (void)net_addr2ip(args[i++], &input.local_ip); (void)net_addr2ip(args[i++], &input.remote_ip); input.username = args[i++]; input.userdb_fields = args + i; env_put(t_strconcat("LOCAL_IP=", net_ip2addr(&input.local_ip), NULL)); env_put(t_strconcat("IP=", net_ip2addr(&input.remote_ip), NULL)); env_put(t_strconcat("USER="******"%s ", key); } } env_put(t_strconcat(ENV_USERDB_KEYS"=", str_c(keys), NULL)); master_service_init_log(master_service, t_strdup_printf("script-login(%s): ", input.username)); service_ctx = mail_storage_service_init(master_service, NULL, flags); if (mail_storage_service_lookup(service_ctx, &input, &user, &error) <= 0) i_fatal("%s", error); mail_storage_service_restrict_setenv(service_ctx, user); if (drop_privileges) restrict_access_by_env(getenv("HOME"), TRUE); if (dup2(fd, STDIN_FILENO) < 0) i_fatal("dup2() failed: %m"); if (dup2(fd, STDOUT_FILENO) < 0) i_fatal("dup2() failed: %m"); if (conn->fd != SCRIPT_COMM_FD) { if (dup2(conn->fd, SCRIPT_COMM_FD) < 0) i_fatal("dup2() failed: %m"); } /* close all listener sockets */ socket_count = master_service_get_socket_count(master_service); for (i = 0; i < socket_count; i++) { if (close(MASTER_LISTEN_FD_FIRST + i) < 0) i_error("close(listener) failed: %m"); } if (close(MASTER_STATUS_FD) < 0) i_error("close(status) failed: %m"); execvp_const(exec_args[0], exec_args); }
static int uri_parse_host(struct uri_parser *parser, struct uri_authority *auth) { const unsigned char *preserve; struct in_addr ip4; struct in6_addr ip6; string_t *literal = NULL; int ret; /* RFC 3986: * * host = IP-literal / IPv4address / reg-name */ literal = uri_parser_get_tmpbuf(parser, 256); /* IP-literal / */ if (parser->cur < parser->end && *parser->cur == '[') { #ifdef HAVE_IPV6 if ((ret=uri_parse_ip_literal(parser, literal, &ip6)) <= 0) return -1; if (auth != NULL) { auth->host_literal = t_strdup(str_c(literal)); auth->host_ip.family = AF_INET6; auth->host_ip.u.ip6 = ip6; auth->have_host_ip = TRUE; } return 1; #else parser->error = "IPv6 host address is not supported"; return -1; #endif } /* IPv4address / * * If it fails to parse, we try to parse it as a reg-name */ preserve = parser->cur; if ((ret = uri_parse_ipv4address(parser, literal, &ip4)) > 0) { if (auth != NULL) { auth->host_literal = t_strdup(str_c(literal)); auth->host_ip.family = AF_INET; auth->host_ip.u.ip4 = ip4; auth->have_host_ip = TRUE; } return ret; } parser->cur = preserve; str_truncate(literal, 0); /* reg-name */ if ((ret = uri_parse_reg_name(parser, literal)) != 0) { if (ret > 0 && auth != NULL) { auth->host_literal = t_strdup(str_c(literal)); auth->have_host_ip = FALSE; } return ret; } return 0; }
net_set_nonblock(fd, FALSE); input = i_stream_create_fd(fd, (size_t)-1); cmd = t_str_new(10); str_append(cmd, "RESET"); /* XXX: Not supported yet. for(ptr = items; *ptr; ptr++) { str_append_c(cmd, '\t'); str_append(cmd, *ptr); } */ str_append_c(cmd, '\n'); /* send command */ ret = write_full(fd, str_c(cmd), str_len(cmd)); if (ret < 0) { i_close_fd(&fd); i_error("write(%s) failed: %m", path); return; } line = i_stream_read_next_line(input); if (line == NULL) { i_error("read(%s) failed: %s", path, i_stream_get_error(input)); } else if (strncmp(line, "OK", 2) != 0) { i_error("%s",line); } else { i_info("Stats reset");
static bool cmd_copy_full(struct client_command_context *cmd, bool move) { struct client *client = cmd->client; struct mail_storage *dest_storage; struct mailbox *destbox; struct mailbox_transaction_context *t, *src_trans; struct mail_search_args *search_args; const char *messageset, *mailbox, *src_uidset; enum mailbox_sync_flags sync_flags = 0; enum imap_sync_flags imap_flags = 0; struct mail_transaction_commit_changes changes; unsigned int copy_count; string_t *msg; int ret; /* <message set> <mailbox> */ if (!client_read_string_args(cmd, 2, &messageset, &mailbox)) return FALSE; if (!client_verify_open_mailbox(cmd)) return TRUE; ret = imap_search_get_seqset(cmd, messageset, cmd->uid, &search_args); if (ret <= 0) return ret < 0; if (client_open_save_dest_box(cmd, mailbox, &destbox) < 0) { mail_search_args_unref(&search_args); return TRUE; } t = mailbox_transaction_begin(destbox, MAILBOX_TRANSACTION_FLAG_EXTERNAL | MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS); ret = fetch_and_copy(client, move, t, &src_trans, search_args, &src_uidset, ©_count); mail_search_args_unref(&search_args); msg = t_str_new(256); if (ret <= 0) mailbox_transaction_rollback(&t); else if (mailbox_transaction_commit_get_changes(&t, &changes) < 0) { if (mailbox_get_last_mail_error(destbox) == MAIL_ERROR_EXPUNGED) { /* storage backend didn't notice the expunge until at commit time. */ ret = 0; } else { ret = -1; } } else if (copy_count == 0) { str_append(msg, "OK No messages found."); pool_unref(&changes.pool); } else if (seq_range_count(&changes.saved_uids) == 0 || changes.no_read_perm) { /* not supported by backend (virtual) or no read permissions for mailbox */ str_append(msg, move ? "OK Move completed." : "OK Copy completed."); pool_unref(&changes.pool); } else if (move) { i_assert(copy_count == seq_range_count(&changes.saved_uids)); copy_update_trashed(client, destbox, copy_count); str_printfa(msg, "* OK [COPYUID %u %s ", changes.uid_validity, src_uidset); imap_write_seq_range(msg, &changes.saved_uids); str_append(msg, "] Moved UIDs."); client_send_line(client, str_c(msg)); str_truncate(msg, 0); str_append(msg, "OK Move completed."); pool_unref(&changes.pool); } else { i_assert(copy_count == seq_range_count(&changes.saved_uids)); copy_update_trashed(client, destbox, copy_count); str_printfa(msg, "OK [COPYUID %u %s ", changes.uid_validity, src_uidset); imap_write_seq_range(msg, &changes.saved_uids); str_append(msg, "] Copy completed."); pool_unref(&changes.pool); } if (ret <= 0 && move) { /* move failed, don't expunge anything */ mailbox_transaction_rollback(&src_trans); } else { if (mailbox_transaction_commit(&src_trans) < 0) ret = -1; } dest_storage = mailbox_get_storage(destbox); if (destbox != client->mailbox) { if (move) sync_flags |= MAILBOX_SYNC_FLAG_EXPUNGE; else sync_flags |= MAILBOX_SYNC_FLAG_FAST; imap_flags |= IMAP_SYNC_FLAG_SAFE; mailbox_free(&destbox); } else if (move) { sync_flags |= MAILBOX_SYNC_FLAG_EXPUNGE; imap_flags |= IMAP_SYNC_FLAG_SAFE; } if (ret > 0) return cmd_sync(cmd, sync_flags, imap_flags, str_c(msg)); else if (ret == 0) { /* some messages were expunged, sync them */ return cmd_sync(cmd, 0, 0, "NO ["IMAP_RESP_CODE_EXPUNGEISSUED"] " "Some of the requested messages no longer exist."); } else { client_send_storage_error(cmd, dest_storage); return TRUE; } }
static int json_parse_string(struct json_parser *parser, bool allow_skip, const char **value_r) { if (*parser->data != '"') return -1; parser->data++; if (parser->skipping && allow_skip) { *value_r = NULL; return json_skip_string(parser); } str_truncate(parser->value, 0); for (; parser->data != parser->end; parser->data++) { if (*parser->data == '"') { parser->data++; *value_r = str_c(parser->value); return 1; } if (*parser->data != '\\') str_append_c(parser->value, *parser->data); else { if (++parser->data == parser->end) return 0; switch (*parser->data) { case '"': case '\\': case '/': str_append_c(parser->value, *parser->data); break; case 'b': str_append_c(parser->value, '\b'); break; case 'f': str_append_c(parser->value, '\f'); break; case 'n': str_append_c(parser->value, '\n'); break; case 'r': str_append_c(parser->value, '\r'); break; case 't': str_append_c(parser->value, '\t'); break; case 'u': parser->data++; if (parser->end - parser->data < 4) { /* wait for more data */ parser->data = parser->end; return 0; } uni_ucs4_to_utf8_c(hex2dec(parser->data, 4), parser->value); parser->data += 3; break; default: return -1; } } } return 0; }
}; bool ext_variables_namespace_argument_activate (const struct sieve_extension *this_ext, struct sieve_validator *valdtr, struct sieve_ast_argument *arg, struct sieve_command *cmd, ARRAY_TYPE(sieve_variable_name) *var_name, bool assignment) { pool_t pool = sieve_command_pool(cmd); struct sieve_ast *ast = arg->ast; const struct sieve_variables_namespace *nspc; struct arg_namespace_variable *var; const struct sieve_variable_name *name_element = array_idx(var_name, 0); void *var_data = NULL; nspc = ext_variables_namespace_create_instance (this_ext, valdtr, cmd, str_c(name_element->identifier)); if ( nspc == NULL ) { sieve_argument_validate_error(valdtr, arg, "referring to variable in unknown namespace '%s'", str_c(name_element->identifier)); return FALSE; } if ( nspc->def != NULL && nspc->def->validate != NULL && !nspc->def->validate (valdtr, nspc, arg, cmd, var_name, &var_data, assignment) ) { return FALSE; } var = p_new(pool, struct arg_namespace_variable, 1); var->namespace = nspc;
//---------------------------------------------------------------------------- qplot_xy_t qplot_read_text( const std::string file, long start, long size, long step, char separator, int xCol, int yCol) { qplot_xy_t data; data.size = 0; qDebug("qplot_read_text(file='%s')", file.c_str()); long cnt = 0; long step_cnt = 0; if (xCol < 0 && yCol < 0) return data; // stupid mission std::ifstream fs(file.c_str()); std::string line; while (std::getline(fs, line)) { if (start != 0) { start--; continue; } if (step_cnt-- != 0) continue; step_cnt = step - 1; if (size != -1 && cnt >= size) break; std::stringstream str_stream(line); std::string cell; std::vector<std::string> cells; cells.clear(); while (std::getline(str_stream, cell, separator)) { //!!! FIXME (use standart trim algoritm next time) str_t str = str_cstr(cell.c_str()); str_t str_trimmed = str_trim(&str); if (separator == ' ') { if (str_size(&str_trimmed)) cells.push_back(str_c(&str_trimmed)); } else cells.push_back(str_c(&str_trimmed)); str_free(&str_trimmed); str_free(&str); } if (yCol < 0) { // xCol >= 0 && yCol < 0 if ((int) cells.size() > xCol) if (cells[yCol].size()) { data.x.push_back(atof(cells[xCol].c_str())); data.y.push_back((double) cnt); cnt++; } } else if (xCol < 0) { // xCol < 0 && yCol >= 0 if ((int) cells.size() > yCol) if (cells[yCol].size()) { data.x.push_back((double) cnt); data.y.push_back(atof(cells[yCol].c_str())); cnt++; } } else { // xCol >= 0 && yCol >= 0 if ((int) cells.size() > xCol && (int) cells.size() > yCol) if (cells[xCol].size() && cells[yCol].size()) { data.x.push_back(atof(cells[xCol].c_str())); data.y.push_back(atof(cells[yCol].c_str())); cnt++; } } } // while (std::getline(fs, line)) data.size = cnt; return data; }
int index_sort_node_cmp_type(struct mail_search_sort_program *program, const enum mail_sort_type *sort_program, uint32_t seq1, uint32_t seq2) { struct mail *mail = program->temp_mail; enum mail_sort_type sort_type; time_t time1, time2; uoff_t size1, size2; float float1, float2; int tz, ret = 0; sort_type = *sort_program & MAIL_SORT_MASK; switch (sort_type) { case MAIL_SORT_CC: case MAIL_SORT_FROM: case MAIL_SORT_TO: case MAIL_SORT_SUBJECT: case MAIL_SORT_DISPLAYFROM: case MAIL_SORT_DISPLAYTO: T_BEGIN { string_t *str1, *str2; str1 = t_str_new(256); str2 = t_str_new(256); if (index_sort_header_get(program, seq1, sort_type, str1) < 0) index_sort_program_set_mail_failed(program, mail); if (index_sort_header_get(program, seq2, sort_type, str2) < 0) index_sort_program_set_mail_failed(program, mail); ret = strcmp(str_c(str1), str_c(str2)); } T_END; break; case MAIL_SORT_ARRIVAL: index_sort_set_seq(program, mail, seq1); if (mail_get_received_date(mail, &time1) < 0) time1 = index_sort_program_set_date_failed(program, mail); index_sort_set_seq(program, mail, seq2); if (mail_get_received_date(mail, &time2) < 0) time2 = index_sort_program_set_date_failed(program, mail); ret = time1 < time2 ? -1 : (time1 > time2 ? 1 : 0); break; case MAIL_SORT_DATE: index_sort_set_seq(program, mail, seq1); if (mail_get_date(mail, &time1, &tz) < 0) time1 = index_sort_program_set_date_failed(program, mail); else if (time1 == 0) { if (mail_get_received_date(mail, &time1) < 0) time1 = index_sort_program_set_date_failed(program, mail); } index_sort_set_seq(program, mail, seq2); if (mail_get_date(mail, &time2, &tz) < 0) time2 = index_sort_program_set_date_failed(program, mail); else if (time2 == 0) { if (mail_get_received_date(mail, &time2) < 0) time2 = index_sort_program_set_date_failed(program, mail); } ret = time1 < time2 ? -1 : (time1 > time2 ? 1 : 0); break; case MAIL_SORT_SIZE: index_sort_set_seq(program, mail, seq1); if (mail_get_virtual_size(mail, &size1) < 0) { index_sort_program_set_mail_failed(program, mail); size1 = 0; } index_sort_set_seq(program, mail, seq2); if (mail_get_virtual_size(mail, &size2) < 0) { index_sort_program_set_mail_failed(program, mail); size2 = 0; } ret = size1 < size2 ? -1 : (size1 > size2 ? 1 : 0); break; case MAIL_SORT_RELEVANCY: index_sort_set_seq(program, mail, seq1); if (index_sort_get_relevancy(mail, &float1) < 0) index_sort_program_set_mail_failed(program, mail); index_sort_set_seq(program, mail, seq2); if (index_sort_get_relevancy(mail, &float2) < 0) index_sort_program_set_mail_failed(program, mail); /* NOTE: higher relevancy is returned first, unlike with all other number based sort keys */ ret = float1 < float2 ? 1 : (float1 > float2 ? -1 : 0); break; case MAIL_SORT_POP3_ORDER: /* 32bit numbers would be enough, but since there is already existing code for uoff_t in sizes, just use them. */ index_sort_set_seq(program, mail, seq1); if (index_sort_get_pop3_order(mail, &size1) < 0) index_sort_program_set_mail_failed(program, mail); index_sort_set_seq(program, mail, seq2); if (index_sort_get_pop3_order(mail, &size2) < 0) index_sort_program_set_mail_failed(program, mail); ret = size1 < size2 ? -1 : (size1 > size2 ? 1 : 0); break; case MAIL_SORT_END: return seq1 < seq2 ? -1 : (seq1 > seq2 ? 1 : 0); case MAIL_SORT_MASK: case MAIL_SORT_FLAG_REVERSE: i_unreached(); } if (ret == 0) { return index_sort_node_cmp_type(program, sort_program+1, seq1, seq2); } if ((*sort_program & MAIL_SORT_FLAG_REVERSE) != 0) ret = ret < 0 ? 1 : -1; return ret; }
//---------------------------------------------------------------------------- // run by mission INI-file bool qplot_run( const char *mission_file, // имя INI-файла задания PlotArea *pa, // указатель на PlotArea : QwtPlot widget QMainWindow *mw) // указатель на PlotWin : QMainWindow { qDebug("qplot_run(mission_file='%s')", mission_file); // open mission INI-file aclass::aini f(mission_file); std::string title = f.read_str("", "title", ""); if (!title.size()) title = mission_file; mw->setWindowTitle("QPlot - " + _QS(title)); QSize wsize = mw->size(); int width = (int) f.read_long("", "width", -1); if (width > 0) wsize.setWidth(width); int height = (int) f.read_long("", "height", -1); if (height > 0) wsize.setHeight(height); if (width > 0 || height > 0) mw->resize(wsize); // read [area] section PlotAreaConf conf = pa->getConf(); qplot_read_conf(&f, "area", &conf); pa->setConf(conf); // off all markers pa->enableMarker(false); pa->enableVLine(false); pa->enableHLine(false); // read [axis] section qplot_read_axis(&f, "axis", pa); if (!f.has_section("0") && !f.has_section("1")) return false; // no curve section // remove all old curves pa->clear(); // read curve description sections [0], [1], [2], ... int begin = (int) f.read_long("", "begin", 0); int end = (int) f.read_long("", "end", 100); for (int i = begin; i <= end; i++) { qplot_xy_t data; str_t tmp = str_int(i); std::string s = str_c(&tmp); str_free(&tmp); if (!f.has_section(s)) continue; std::string file = f.read_str(s, "file", ""); if (file.size() == 0) continue; long start = f.read_long(s, "start", 0); long size = f.read_long(s, "size", -1); long step = f.read_long(s, "step", 1); if (step <= 0) step = 1; std::string fmt = f.read_str(s, "format", "txt"); if (_STRCMP(fmt, "bin" ) == 0 || _STRCMP(fmt, "binary") == 0 || _STRCMP(fmt, "raw" ) == 0) { // binary data file format long recordSize = f.read_long(s, "recordSize"); if (recordSize <= 0) { qDebug("recordSize = %li, skip [%i] section", recordSize, i); continue; } int xOff = (int) f.read_long(s, "xOff", -1); int yOff = (int) f.read_long(s, "yOff", -1); std::string type = f.read_str(s, "xType", "float"); int xType = qplot_id_by_type(type); type = f.read_str(s, "yType", "float"); int yType = qplot_id_by_type(type); data = qplot_read_binary(file, start, size, step, recordSize, xType, yType, xOff, yOff); } else { // text data file format std::string sep = f.read_str(s, "separator", " "); char separator = (sep.size() > 0) ? sep[0] : ' '; int xCol = (int) f.read_long(s, "xCol", -1); int yCol = (int) f.read_long(s, "yCol", -1); data = qplot_read_text(file, start, size, step, separator, xCol, yCol); } if (data.size <= 0) { qDebug("data.size = %i, skip [%i] section", data.size, i); continue; } CurveConf conf; conf.legend = _QS(f.read_str(s, "legend", "")); conf.curve = qplot_qwt_curve_by_name(f.read_str(s, "curve", "lines")); conf.pen = QPen( QColor(f.read_str(s, "color", "black").c_str()), f.read_double(s, "width", conf.curve == QwtPlotCurve::Dots ? 3.0 : 1.0), qplot_pen_by_name(f.read_str(s, "style", "solid"))); conf.symStyle = qplot_qwt_symbol_by_name( f.read_str(s, "symbol", "no")); conf.symPen = QPen( QColor(f.read_str(s, "symColor", "blue").c_str()), f.read_double(s, "symWidth", 1.0), Qt::SolidLine); conf.symBrush = QBrush( QColor(f.read_str(s, "symBrush", "gray").c_str())); conf.symSize = (int) f.read_long(s, "symSize", 7); std::string axis = f.read_str(s, "axisX", "Bottom"); conf.xAxis = !_STRCMP(axis, "Top") ? QwtPlot::xTop : QwtPlot::xBottom; axis = f.read_str(s, "axisY", "Left"); conf.yAxis = !_STRCMP(axis, "Right") ? QwtPlot::yRight : QwtPlot::yLeft; if (data.size) //pa->addCurve(data.x.data(), data.y.data(), data.size, conf /*, false*/); pa->addCurve(&data.x[0], &data.y[0], data.size, conf /*, false*/); } // for (int i = 0; i < num; i++) pa->redraw(); return true; }
static bool cmd_putscript_finish_parsing(struct client_command_context *cmd) { struct client *client = cmd->client; struct cmd_putscript_context *ctx = cmd->context; const struct managesieve_arg *args; int ret; /* if error occurs, the CRLF is already read. */ client->input_skip_line = FALSE; /* <script literal> */ ret = managesieve_parser_read_args(ctx->save_parser, 0, 0, &args); if (ret == -1 || client->output->closed) { if (ctx->storage != NULL) client_send_command_error(cmd, NULL); cmd_putscript_finish(ctx); return TRUE; } if (ret < 0) { /* need more data */ return FALSE; } if ( MANAGESIEVE_ARG_IS_EOL(&args[0]) ) { struct sieve_script *script; bool success = TRUE; /* Eat away the trailing CRLF */ client->input_skip_line = TRUE; /* Obtain script object for uploaded script */ script = sieve_storage_save_get_tempscript(ctx->save_ctx); /* Check result */ if ( script == NULL ) { client_send_storage_error(client, ctx->storage); cmd_putscript_finish(ctx); return TRUE; } /* If quoted string, the size was not known until now */ if ( ctx->script_size == 0 ) { if (sieve_script_get_size(script, &ctx->script_size) < 0) { client_send_storage_error(client, ctx->storage); cmd_putscript_finish(ctx); return TRUE; } /* Check quota; max size is already checked */ if ( ctx->scriptname != NULL && !managesieve_quota_check_all (client, ctx->scriptname, ctx->script_size) ) { cmd_putscript_finish(ctx); return TRUE; } } /* Try to compile script */ T_BEGIN { struct sieve_error_handler *ehandler; enum sieve_compile_flags cpflags = SIEVE_COMPILE_FLAG_NOGLOBAL | SIEVE_COMPILE_FLAG_UPLOADED; struct sieve_binary *sbin; enum sieve_error error; string_t *errors; /* Mark this as an activation when we are replacing the active script */ if ( sieve_storage_save_will_activate(ctx->save_ctx) ) { cpflags |= SIEVE_COMPILE_FLAG_ACTIVATED; } /* Prepare error handler */ errors = str_new(default_pool, 1024); ehandler = sieve_strbuf_ehandler_create(client->svinst, errors, TRUE, client->set->managesieve_max_compile_errors); /* Compile */ if ( (sbin=sieve_compile_script (script, ehandler, cpflags, &error)) == NULL ) { if ( error != SIEVE_ERROR_NOT_VALID ) { const char *errormsg = sieve_script_get_last_error(script, &error); if ( error != SIEVE_ERROR_NONE ) client_send_no(client, errormsg); else client_send_no(client, str_c(errors)); } else { client_send_no(client, str_c(errors)); } success = FALSE; } else { sieve_close(&sbin); /* Commit to save only when this is a putscript command */ if ( ctx->scriptname != NULL ) { ret = sieve_storage_save_commit(&ctx->save_ctx); /* Check commit */ if (ret < 0) { client_send_storage_error(client, ctx->storage); success = FALSE; } } } /* Finish up */ cmd_putscript_finish(ctx); /* Report result to user */ if ( success ) { if ( ctx->scriptname != NULL ) { client->put_count++; client->put_bytes += ctx->script_size; } else { client->check_count++; client->check_bytes += ctx->script_size; } if ( sieve_get_warnings(ehandler) > 0 ) client_send_okresp(client, "WARNINGS", str_c(errors)); else { if ( ctx->scriptname != NULL ) client_send_ok(client, "PUTSCRIPT completed."); else client_send_ok(client, "Script checked successfully."); } } sieve_error_handler_unref(&ehandler); str_free(&errors); } T_END; return TRUE; } client_send_command_error(cmd, "Too many command arguments."); cmd_putscript_finish(ctx); return TRUE; }
int ext_enotify_runtime_check_operands (const struct sieve_runtime_env *renv, string_t *method_uri, string_t *message, string_t *from, struct sieve_stringlist *options, const struct sieve_enotify_method **method_r, void **method_context) { const struct sieve_enotify_method *method; const char *uri_body; /* Get method */ method = ext_enotify_get_method(renv, method_uri, &uri_body); if ( method == NULL ) return SIEVE_EXEC_FAILURE; /* Check provided operands */ if ( method->def != NULL && method->def->runtime_check_operands != NULL ) { struct sieve_enotify_env nenv; int result = SIEVE_EXEC_OK; memset(&nenv, 0, sizeof(nenv)); nenv.svinst = renv->svinst; nenv.method = method; nenv.ehandler = sieve_prefix_ehandler_create (renv->ehandler, sieve_runtime_get_full_command_location(renv), "notify action"); /* Execute check function */ if ( method->def->runtime_check_operands (&nenv, str_c(method_uri), uri_body, message, from, sieve_result_pool(renv->result), method_context) ) { /* Check any provided options */ if ( options != NULL ) { string_t *option = NULL; int ret; /* Iterate through all provided options */ while ( (ret=sieve_stringlist_next_item(options, &option)) > 0 ) { const char *opt_name = NULL, *opt_value = NULL; /* Parse option into <optionname> and <value> */ if ( ext_enotify_option_parse (&nenv, str_c(option), FALSE, &opt_name, &opt_value) ) { /* Set option */ if ( method->def->runtime_set_option != NULL ) { (void) method->def->runtime_set_option (&nenv, *method_context, opt_name, opt_value); } } } /* Check for binary corruptions encountered during string list iteration */ if ( ret >= 0 ) { *method_r = method; } else { /* Binary corrupt */ sieve_runtime_trace_error (renv, "invalid item in options string list"); result = SIEVE_EXEC_BIN_CORRUPT; } } else { /* No options */ *method_r = method; } } else { /* Operand check failed */ result = SIEVE_EXEC_FAILURE; } sieve_error_handler_unref(&nenv.ehandler); return result; } /* No check function defined: a most unlikely situation */ *method_context = NULL; *method_r = method; return SIEVE_EXEC_OK; }
static int client_fetch_url(struct client *client, const char *url, enum imap_urlauth_fetch_flags url_flags) { string_t *response; const char *bpstruct, *errormsg; bool binary_with_nuls; int ret; i_assert(client->url == NULL); client->msg_part_size = 0; client->msg_part_input = NULL; if (client->debug) i_debug("Fetching URLAUTH %s", url); /* fetch URL */ ret = client_fetch_urlpart(client, url, url_flags, &bpstruct, &binary_with_nuls, &errormsg); if (ret <= 0) { /* fetch failed */ if (client->url != NULL) imap_msgpart_url_free(&client->url); /* don't send error details to anonymous users: just to be sure that no information about the target user account is unduly leaked. */ if (client->access_anonymous || errormsg == NULL) client_send_line(client, "NO"); else { client_send_line(client, "NO\terror=%s", str_tabescape(errormsg)); } if (ret < 0) { /* fetch failed badly */ client_abort(client, "Session aborted: Fatal failure while fetching URL"); } return 0; } response = t_str_new(256); str_append(response, "OK"); if (binary_with_nuls) str_append(response, "\thasnuls"); if (bpstruct != NULL) { str_append(response, "\tbpstruct="); str_append(response, str_tabescape(bpstruct)); if (client->debug) { i_debug("Fetched URLAUTH yielded BODYPARTSTRUCTURE (%s)", bpstruct); } } /* return content */ o_stream_cork(client->output); if (client->msg_part_size == 0 || client->msg_part_input == NULL) { /* empty */ str_append(response, "\t0"); client_send_line(client, "%s", str_c(response)); imap_msgpart_url_free(&client->url); client->url = NULL; if (client->debug) i_debug("Fetched URLAUTH yielded empty result"); } else { /* actual content */ str_printfa(response, "\t%"PRIuUOFF_T, client->msg_part_size); client_send_line(client, "%s", str_c(response)); if (client->debug) { i_debug("Fetched URLAUTH yielded %"PRIuUOFF_T" bytes " "of %smessage data", client->msg_part_size, (binary_with_nuls ? "binary " : "")); } if (client_run_url(client) < 0) { client_abort(client, "Session aborted: Fatal failure while transfering URL"); return 0; } } if (client->url != NULL) { /* URL not finished */ o_stream_set_flush_pending(client->output, TRUE); client->waiting_input = TRUE; } o_stream_uncork(client->output); return client->url != NULL ? 0 : 1; }
int str_to_int(const str *string, int *result) { *result = atoi(str_c(string)); return 1; }
mkdir_chown_full(const char *path, mode_t mode, uid_t uid, gid_t gid, const char *gid_origin) { string_t *str; mode_t old_mask; int ret, orig_errno; old_mask = umask(0); ret = mkdir(path, mode); umask(old_mask); if (ret < 0) { if (errno == EISDIR || errno == ENOSYS) { /* EISDIR check is for BSD/OS which returns it if path contains '/' at the end and it exists. ENOSYS check is for NFS mount points. */ errno = EEXIST; } return -1; } if (chown(path, uid, gid) < 0) { orig_errno = errno; if (rmdir(path) < 0) i_error("rmdir(%s) failed: %m", path); errno = orig_errno; if (errno == EPERM && uid == (uid_t)-1) { i_error("%s", eperm_error_get_chgrp("chown", path, gid, gid_origin)); return -1; } str = t_str_new(256); str_printfa(str, "chown(%s, %ld", path, uid == (uid_t)-1 ? -1L : (long)uid); if (uid != (uid_t)-1) { struct passwd pw; if (i_getpwuid(uid, &pw) > 0) str_printfa(str, "(%s)", pw.pw_name); } str_printfa(str, ", %ld", gid == (gid_t)-1 ? -1L : (long)gid); if (gid != (gid_t)-1) { struct group gr; if (i_getgrgid(uid, &gr) > 0) str_printfa(str, "(%s)", gr.gr_name); } errno = orig_errno; i_error("%s) failed: %m", str_c(str)); return -1; } if (gid != (gid_t)-1 && (mode & S_ISGID) == 0) { /* make sure the directory doesn't have setgid bit enabled (in case its parent had) */ if (chmod(path, mode) < 0) { orig_errno = errno; if (rmdir(path) < 0) i_error("rmdir(%s) failed: %m", path); errno = orig_errno; i_error("chmod(%s) failed: %m", path); return -1; } } return 0; }
int str_to_float(const str *string, float *result) { *result = atof(str_c(string)); return 1; }
int index_sort_node_cmp_type(struct mail *mail, const enum mail_sort_type *sort_program, uint32_t seq1, uint32_t seq2) { enum mail_sort_type sort_type; time_t time1, time2; uoff_t size1, size2; float float1, float2; int ret = 0; sort_type = *sort_program & MAIL_SORT_MASK; switch (sort_type) { case MAIL_SORT_CC: case MAIL_SORT_FROM: case MAIL_SORT_TO: case MAIL_SORT_SUBJECT: case MAIL_SORT_DISPLAYFROM: case MAIL_SORT_DISPLAYTO: T_BEGIN { string_t *str1, *str2; str1 = t_str_new(256); str2 = t_str_new(256); index_sort_header_get(mail, seq1, sort_type, str1); index_sort_header_get(mail, seq2, sort_type, str2); ret = strcmp(str_c(str1), str_c(str2)); } T_END; break; case MAIL_SORT_ARRIVAL: mail_set_seq(mail, seq1); if (mail_get_received_date(mail, &time1) < 0) time1 = 0; mail_set_seq(mail, seq2); if (mail_get_received_date(mail, &time2) < 0) time1 = 0; ret = time1 < time2 ? -1 : (time1 > time2 ? 1 : 0); break; case MAIL_SORT_DATE: mail_set_seq(mail, seq1); if (mail_get_date(mail, &time1, NULL) < 0) time1 = 0; else if (time1 == 0) { if (mail_get_received_date(mail, &time1) < 0) time1 = 0; } mail_set_seq(mail, seq2); if (mail_get_date(mail, &time2, NULL) < 0) time2 = 0; else if (time2 == 0) { if (mail_get_received_date(mail, &time2) < 0) time2 = 0; } ret = time1 < time2 ? -1 : (time1 > time2 ? 1 : 0); break; case MAIL_SORT_SIZE: mail_set_seq(mail, seq1); if (mail_get_virtual_size(mail, &size1) < 0) size1 = 0; mail_set_seq(mail, seq2); if (mail_get_virtual_size(mail, &size2) < 0) size2 = 0; ret = size1 < size2 ? -1 : (size1 > size2 ? 1 : 0); break; case MAIL_SORT_SEARCH_SCORE: mail_set_seq(mail, seq1); float1 = index_sort_get_score(mail); mail_set_seq(mail, seq2); float2 = index_sort_get_score(mail); ret = float1 < float2 ? -1 : (float1 > float2 ? 1 : 0); break; case MAIL_SORT_END: return seq1 < seq2 ? -1 : (seq1 > seq2 ? 1 : 0); case MAIL_SORT_MASK: case MAIL_SORT_FLAG_REVERSE: i_unreached(); } if (ret == 0) { return index_sort_node_cmp_type(mail, sort_program+1, seq1, seq2); } if ((*sort_program & MAIL_SORT_FLAG_REVERSE) != 0) ret = ret < 0 ? 1 : -1; return ret; }
int str_to_long(const str *string, long *result) { *result = atol(str_c(string)); return 1; }
void imap_client_auth_result(struct client *client, enum client_auth_result result, const struct client_auth_reply *reply, const char *text) { struct imap_url url; string_t *referral; switch (result) { case CLIENT_AUTH_RESULT_SUCCESS: /* nothing to be done for IMAP */ break; case CLIENT_AUTH_RESULT_REFERRAL_SUCCESS: case CLIENT_AUTH_RESULT_REFERRAL_NOLOGIN: /* IMAP referral [nologin] referral host=.. [port=..] [destuser=..] [reason=..] NO [REFERRAL imap://destuser;AUTH=..@host:port/] Can't login. OK [...] Logged in, but you should use this server instead. .. [REFERRAL ..] (Reason from auth server) */ referral = t_str_new(128); i_zero(&url); url.userid = reply->destuser; url.auth_type = client->auth_mech_name; url.host.name = reply->host; if (reply->port != 143) url.port = reply->port; str_append(referral, "REFERRAL "); str_append(referral, imap_url_create(&url)); if (result == CLIENT_AUTH_RESULT_REFERRAL_SUCCESS) { client_send_reply_code(client, IMAP_CMD_REPLY_OK, str_c(referral), text); } else { client_send_reply_code(client, IMAP_CMD_REPLY_NO, str_c(referral), text); } break; case CLIENT_AUTH_RESULT_INVALID_BASE64: case CLIENT_AUTH_RESULT_ABORTED: client_send_reply(client, IMAP_CMD_REPLY_BAD, text); break; case CLIENT_AUTH_RESULT_AUTHFAILED_REASON: case CLIENT_AUTH_RESULT_MECH_INVALID: if (text[0] == '[') client_send_reply(client, IMAP_CMD_REPLY_NO, text); else { client_send_reply_code(client, IMAP_CMD_REPLY_NO, "ALERT", text); } break; case CLIENT_AUTH_RESULT_AUTHZFAILED: client_send_reply_code(client, IMAP_CMD_REPLY_NO, IMAP_RESP_CODE_AUTHZFAILED, text); break; case CLIENT_AUTH_RESULT_TEMPFAIL: client_send_reply_code(client, IMAP_CMD_REPLY_NO, IMAP_RESP_CODE_UNAVAILABLE, text); break; case CLIENT_AUTH_RESULT_SSL_REQUIRED: case CLIENT_AUTH_RESULT_MECH_SSL_REQUIRED: client_send_reply_code(client, IMAP_CMD_REPLY_NO, IMAP_RESP_CODE_PRIVACYREQUIRED, text); break; case CLIENT_AUTH_RESULT_PASS_EXPIRED: client_send_reply_code(client, IMAP_CMD_REPLY_NO, IMAP_RESP_CODE_EXPIRED, text); break; case CLIENT_AUTH_RESULT_LOGIN_DISABLED: client_send_reply_code(client, IMAP_CMD_REPLY_NO, IMAP_RESP_CODE_CONTACTADMIN, text); break; case CLIENT_AUTH_RESULT_AUTHFAILED: client_send_reply_code(client, IMAP_CMD_REPLY_NO, IMAP_RESP_CODE_AUTHFAILED, text); break; } }
static int imap_master_client_input_args(struct connection *conn, const char *const *args, int fd_client, pool_t pool) { struct imap_master_client *client = (struct imap_master_client *)conn; struct client *imap_client; struct mail_storage_service_input input; struct imap_master_input master_input; const char *error; int ret; if (imap_master_client_parse_input(args, pool, &input, &master_input, &error) < 0) { i_error("imap-master: Failed to parse client input: %s", error); o_stream_nsend_str(conn->output, t_strdup_printf( "-Failed to parse client input: %s\n", error)); i_close_fd(&fd_client); return -1; } if (imap_master_client_verify(&master_input, fd_client, &error) < 0) { i_error("imap-master: Failed to verify client input: %s", error); o_stream_nsend_str(conn->output, t_strdup_printf( "-Failed to verify client input: %s\n", error)); i_close_fd(&fd_client); return -1; } /* Send a success notification before we start anything that lasts potentially a long time. imap-hibernate process is waiting for us to answer. Even if we fail later, we log the error anyway. */ o_stream_nsend_str(conn->output, "+\n"); (void)o_stream_flush(conn->output); /* NOTE: before client_create_from_input() on failures we need to close fd_client, but afterward it gets closed by client_destroy() */ ret = client_create_from_input(&input, fd_client, fd_client, &imap_client, &error); if (ret < 0) { i_error("imap-master(%s): Failed to create client: %s", input.username, error); i_close_fd(&fd_client); return -1; } client->imap_client_created = TRUE; if (client_create_finish(imap_client, &error) < 0) { i_error("imap-master(%s): %s", input.username, error); client_destroy(imap_client, error); return -1; } /* log prefix is set at this point, so we don't need to add the username anymore to the log messages */ o_stream_nsend(imap_client->output, master_input.client_output->data, master_input.client_output->used); if (master_input.client_input->used > 0 && !i_stream_add_data(imap_client->input, master_input.client_input->data, master_input.client_input->used)) { i_error("imap-master: Couldn't add %"PRIuSIZE_T " bytes to client's input stream", master_input.client_input->used); client_destroy(imap_client, "Client initialization failed"); return -1; } imap_client->state_import_bad_idle_done = master_input.state_import_bad_idle_done; imap_client->state_import_idle_continue = master_input.state_import_idle_continue; if (imap_client->user->mail_debug) { if (imap_client->state_import_bad_idle_done) i_debug("imap-master: Unhibernated because IDLE was stopped with BAD command"); else if (imap_client->state_import_idle_continue) i_debug("imap-master: Unhibernated to send mailbox changes"); else i_debug("imap-master: Unhibernated because IDLE was stopped with DONE"); } ret = imap_state_import_internal(imap_client, master_input.state->data, master_input.state->used, &error); if (ret <= 0) { i_error("imap-master: Failed to import client state: %s", error); client_destroy(imap_client, "Client state initialization failed"); return -1; } if (master_input.tag != NULL) imap_state_import_idle_cmd_tag(imap_client, master_input.tag); /* make sure all pending input gets handled */ i_assert(imap_client->to_delayed_input == NULL); if (master_input.client_input->used > 0) { if (imap_client->user->mail_debug) { i_debug("imap-master: Pending client input: '%s'", str_sanitize(str_c(master_input.client_input), 128)); } imap_client->to_delayed_input = timeout_add(0, client_input, imap_client); } imap_refresh_proctitle(); /* we'll always disconnect the client afterwards */ return -1; }