static bool stats_top_round(struct top_context *ctx) { #define TOP_CMD "EXPORT\tsession\tconnected\n" const char *const *args; pool_t tmp_pool; if (write_full(ctx->fd, TOP_CMD, strlen(TOP_CMD)) < 0) i_fatal("write(%s) failed: %m", ctx->path); /* read header */ if (ctx->headers != NULL) { args = read_next_line(ctx->input); if (args == NULL) i_fatal("read(%s) unexpectedly disconnected", ctx->path); if (*args == NULL) return TRUE; if (str_array_length(args) != ctx->headers_count) i_fatal("headers changed"); } else { ctx->headers = p_read_next_line(default_pool, ctx->input); if (ctx->headers == NULL) i_fatal("read(%s) unexpectedly disconnected", ctx->path); if (*ctx->headers == NULL) { i_free_and_null(ctx->headers); return FALSE; } ctx->headers_count = str_array_length((void *)ctx->headers); if (!stats_header_find(ctx, "last_update", &ctx->last_update_idx)) i_fatal("last_update header missing"); if (!stats_header_find(ctx, "user", &ctx->user_idx)) i_fatal("user header missing"); stats_top_get_sorting(ctx); } array_clear(&ctx->lines); p_clear(ctx->prev_pool); tmp_pool = ctx->prev_pool; ctx->prev_pool = ctx->cur_pool; ctx->cur_pool = tmp_pool; ctx->flip = !ctx->flip; stats_read(ctx); stats_drop_stale(ctx); sort_ctx = ctx; array_sort(&ctx->lines, *ctx->lines_sort); sort_ctx = NULL; return TRUE; }
int connection_verify_version(struct connection *conn, const char *const *args) { unsigned int recv_major_version; /* VERSION <tab> service_name <tab> major version <tab> minor version */ if (str_array_length(args) != 4 || strcmp(args[0], "VERSION") != 0 || str_to_uint(args[2], &recv_major_version) < 0 || str_to_uint(args[3], &conn->minor_version) < 0) { i_error("%s didn't reply with a valid VERSION line", conn->name); return -1; } if (strcmp(args[1], conn->list->set.service_name_in) != 0) { i_error("%s: Connected to wrong socket type. " "We want '%s', but received '%s'", conn->name, conn->list->set.service_name_in, args[1]); return -1; } if (recv_major_version != conn->list->set.major_version) { i_error("%s: Socket supports major version %u, " "but we support only %u (mixed old and new binaries?)", conn->name, recv_major_version, conn->list->set.major_version); return -1; } return 0; }
static void cmd_import_init(struct doveadm_mail_cmd_context *_ctx, const char *const args[]) { struct import_cmd_context *ctx = (struct import_cmd_context *)_ctx; struct mail_storage_service_input input; struct mail_storage_service_user *service_user; struct mail_user *user; const char *src_location, *error, *userdb_fields[2]; if (str_array_length(args) < 3) doveadm_mail_help_name("import"); src_location = args[0]; ctx->dest_parent = p_strdup(_ctx->pool, args[1]); ctx->ctx.search_args = doveadm_mail_build_search_args(args+2); /* @UNSAFE */ userdb_fields[0] = t_strconcat("mail=", src_location, NULL); userdb_fields[1] = NULL; /* create a user for accessing the source storage */ memset(&input, 0, sizeof(input)); input.module = "module"; input.username = "******"; input.no_userdb_lookup = TRUE; input.userdb_fields = userdb_fields; if (mail_storage_service_lookup_next(ctx->ctx.storage_service, &input, &service_user, &user, &error) < 0) i_fatal("Import user initialization failed: %s", error); ctx->src_user = user; mail_storage_service_user_free(&service_user); }
static void stats_read(struct top_context *ctx) { struct top_line *old_line, *line; unsigned int i; char **args; /* read lines */ while ((args = p_read_next_line(ctx->cur_pool, ctx->input)) != NULL) { if (args[0] == NULL) { /* end of stats */ return; } if (str_array_length((void *)args) != ctx->headers_count) i_fatal("read(%s): invalid stats line", ctx->path); line = p_new(ctx->cur_pool, struct top_line, 1); line->id = args[0]; line->flip = ctx->flip; line->cur_values = p_new(ctx->cur_pool, const char *, ctx->headers_count); for (i = 0; i < ctx->headers_count; i++) line->cur_values[i] = args[i]; old_line = hash_table_lookup(ctx->sessions, line->id); if (old_line != NULL) { stats_line_set_prev_values(ctx, old_line, line); array_append(&ctx->lines, &line, 1); } hash_table_insert(ctx->sessions, line->id, line); } if (ctx->input->stream_errno != 0) i_fatal("read(%s) failed: %m", ctx->path); i_fatal("read(%s): unexpected EOF", ctx->path); }
static void cmd_import_init(struct doveadm_mail_cmd_context *_ctx, const char *const args[]) { struct import_cmd_context *ctx = (struct import_cmd_context *)_ctx; struct mail_storage_service_input input; struct mail_storage_service_user *service_user; struct mail_user *user; const char *src_location, *error; if (str_array_length(args) < 3) doveadm_mail_help_name("import"); src_location = args[0]; ctx->dest_parent = p_strdup(_ctx->pool, args[1]); ctx->ctx.search_args = doveadm_mail_build_search_args(args+2); /* create a user for accessing the source storage */ memset(&input, 0, sizeof(input)); input.module = "mail"; input.username = "******"; input.flags_override_add = MAIL_STORAGE_SERVICE_FLAG_NO_NAMESPACES | MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS; input.flags_override_remove = MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP; if (mail_storage_service_lookup_next(ctx->ctx.storage_service, &input, &service_user, &user, &error) < 0) i_fatal("Import user initialization failed: %s", error); if (mail_namespaces_init_location(user, src_location, &error) < 0) i_fatal("Import namespace initialization failed: %s", error); ctx->src_user = user; mail_storage_service_user_free(&service_user); }
int mail_session_connect_parse(const char *const *args, const char **error_r) { struct mail_session *session; const char *session_id; pid_t pid; struct ip_addr ip; unsigned int i; /* <session id> <username> <service> <pid> [key=value ..] */ if (str_array_length(args) < 4) { *error_r = "CONNECT: Too few parameters"; return -1; } session_id = args[0]; if (str_to_pid(args[3], &pid) < 0) { *error_r = t_strdup_printf("CONNECT: Invalid pid %s for session ID %s", args[3], session_id); return -1; } session = hash_table_lookup(mail_sessions_hash, session_id); if (session != NULL) { *error_r = t_strdup_printf( "CONNECT: Duplicate session ID %s for user %s service %s", session_id, args[1], args[2]); return -1; } session = i_malloc(sizeof(struct mail_session) + stats_alloc_size()); session->stats = (void *)(session + 1); session->refcount = 1; /* unrefed at disconnect */ session->id = i_strdup(session_id); session->service = str_table_ref(services, args[2]); session->pid = pid; session->last_update = ioloop_timeval; session->to_idle = timeout_add(MAIL_SESSION_IDLE_TIMEOUT_MSECS, mail_session_idle_timeout, session); session->user = mail_user_login(args[1]); for (i = 3; args[i] != NULL; i++) { if (strncmp(args[i], "rip=", 4) == 0 && net_addr2ip(args[i] + 4, &ip) == 0) session->ip = mail_ip_login(&ip); } hash_table_insert(mail_sessions_hash, session->id, session); DLLIST_PREPEND_FULL(&stable_mail_sessions, session, stable_prev, stable_next); DLLIST2_APPEND_FULL(&mail_sessions_head, &mail_sessions_tail, session, sorted_prev, sorted_next); DLLIST_PREPEND_FULL(&session->user->sessions, session, user_prev, user_next); mail_user_ref(session->user); if (session->ip != NULL) { DLLIST_PREPEND_FULL(&session->ip->sessions, session, ip_prev, ip_next); mail_ip_ref(session->ip); } global_memory_alloc(mail_session_memsize(session)); return 0; }
static int client_input_notify(struct doveadm_connection *client, const char *const *args) { struct replicator_user *user; /* <username> <flags> <state> */ if (str_array_length(args) < 3) { i_error("%s: NOTIFY: Invalid parameters", client->conn.name); return -1; } user = replicator_queue_add(client->queue, args[0], REPLICATION_PRIORITY_NONE); if (args[1][0] == 'f') user->last_full_sync = ioloop_time; user->last_fast_sync = ioloop_time; user->last_update = ioloop_time; if (args[2][0] != '\0') { i_free(user->state); user->state = i_strdup(args[2]); } o_stream_send_str(client->conn.output, "+\n"); return 0; }
static void search_update_flag_changes(struct dsync_mailbox_exporter *exporter, struct mail *mail, struct dsync_mail_change *change) { const char *const *keywords; unsigned int i; char type; i_assert((change->add_flags & change->remove_flags) == 0); change->modseq = mail_get_modseq(mail); change->pvt_modseq = mail_get_pvt_modseq(mail); change->final_flags = mail_get_flags(mail); keywords = mail_get_keywords(mail); if (!array_is_created(&change->keyword_changes) && keywords[0] != NULL) { p_array_init(&change->keyword_changes, exporter->pool, str_array_length(keywords)); } for (i = 0; keywords[i] != NULL; i++) { /* add the final keyword if it's not already there as +keyword */ if (!final_keyword_check(change, keywords[i], &type)) { const char *keyword_change = p_strdup_printf(exporter->pool, "%c%s", type, keywords[i]); array_append(&change->keyword_changes, &keyword_change, 1); } } }
static void cmd_director_status_user(struct director_context *ctx, char *argv[]) { const char *user = argv[0], *tag = argv[1]; const char *line, *const *args; unsigned int expires; director_send(ctx, t_strdup_printf("USER-LOOKUP\t%s\t%s\n", user, tag != NULL ? tag : "")); line = i_stream_read_next_line(ctx->input); if (line == NULL) { i_error("Lookup failed"); doveadm_exit_code = EX_TEMPFAIL; return; } args = t_strsplit_tab(line); if (str_array_length(args) != 4 || str_to_uint(args[1], &expires) < 0) { i_error("Invalid reply from director"); doveadm_exit_code = EX_PROTOCOL; return; } if (args[0][0] != '\0') { printf("Current: %s (expires %s)\n", args[0], unixdate2str(expires)); } else { printf("Current: not assigned\n"); } printf("Hashed: %s\n", args[2]); printf("Initial config: %s\n", args[3]); director_disconnect(ctx); }
static void cmd_import_init(struct doveadm_mail_cmd_context *_ctx, const char *const args[]) { struct import_cmd_context *ctx = (struct import_cmd_context *)_ctx; if (str_array_length(args) < 3) doveadm_mail_help_name("import"); ctx->src_location = p_strdup(_ctx->pool, args[0]); ctx->dest_parent = p_strdup(_ctx->pool, args[1]); ctx->ctx.search_args = doveadm_mail_build_search_args(args+2); }
static const char * file_lock_find_proc_locks(int lock_fd ATTR_UNUSED) { /* do anything except Linux support this? don't bother trying it for OSes we don't know about. */ #ifdef __linux__ static bool have_proc_locks = TRUE; struct stat st; char node_buf[MAX_INT_STRLEN*3 + 2 + 1]; struct istream *input; const char *line, *lock_type = ""; pid_t pid = 0; int fd; if (!have_proc_locks) return FALSE; if (fstat(lock_fd, &st) < 0) return ""; i_snprintf(node_buf, sizeof(node_buf), "%02x:%02x:%llu", major(st.st_dev), minor(st.st_dev), (unsigned long long)st.st_ino); fd = open("/proc/locks", O_RDONLY); if (fd == -1) { have_proc_locks = FALSE; return ""; } input = i_stream_create_fd_autoclose(&fd, 512); while (pid == 0 && (line = i_stream_read_next_line(input)) != NULL) T_BEGIN { const char *const *args = t_strsplit_spaces(line, " "); /* number: FLOCK/POSIX ADVISORY READ/WRITE pid major:minor:inode region-start region-end */ if (str_array_length(args) < 8) continue; if (strcmp(args[5], node_buf) == 0) { lock_type = strcmp(args[3], "READ") == 0 ? "READ" : "WRITE"; if (str_to_pid(args[4], &pid) < 0) pid = 0; } } T_END; i_stream_destroy(&input); if (pid == 0) { /* not found */ return ""; } if (pid == getpid()) return " (BUG: lock is held by our own process)"; return t_strdup_printf(" (%s lock held by pid %ld)", lock_type, (long)pid); #else return ""; #endif }
static void cmd_sieve_activate_init (struct doveadm_mail_cmd_context *_ctx, const char *const args[]) { struct doveadm_sieve_activate_cmd_context *ctx = (struct doveadm_sieve_activate_cmd_context *)_ctx; if (str_array_length(args) != 1) doveadm_mail_help_name("sieve activate"); doveadm_sieve_cmd_scriptnames_check(args); ctx->scriptname = p_strdup(ctx->ctx.ctx.pool, args[0]); }
static void cmd_mailbox_metadata_unset_init(struct doveadm_mail_cmd_context *_ctx, const char *const args[]) { struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx; const char *key; if (str_array_length(args) != 2) doveadm_mail_help_name("mailbox metadata unset"); cmd_mailbox_metadata_parse_key(args[1], &ctx->key_type, &key); ctx->mailbox = p_strdup(_ctx->pool, args[0]); ctx->key = p_strdup(_ctx->pool, key); }
static void cmd_director_status(int argc, char *argv[]) { struct director_context *ctx; const char *line, *const *args; ctx = cmd_director_init(argc, argv, "a:t:", cmd_director_status); if (argv[optind] != NULL) { cmd_director_status_user(ctx, argv+optind); return; } doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE); doveadm_print_header_simple("mail server ip"); doveadm_print_header_simple("tag"); doveadm_print_header_simple("vhosts"); doveadm_print_header_simple("state"); doveadm_print_header("state-changed", "state changed", 0); doveadm_print_header_simple("users"); director_send(ctx, "HOST-LIST\n"); while ((line = i_stream_read_next_line(ctx->input)) != NULL) { if (*line == '\0') break; T_BEGIN { unsigned int arg_count; time_t ts; args = t_strsplit_tab(line); arg_count = str_array_length(args); if (arg_count >= 6) { /* ip vhosts users tag updown updown-ts */ doveadm_print(args[0]); doveadm_print(args[3]); doveadm_print(args[1]); doveadm_print(args[4][0] == 'D' ? "down" : "up"); if (str_to_time(args[5], &ts) < 0 || ts <= 0) doveadm_print("-"); else doveadm_print(unixdate2str(ts)); doveadm_print(args[2]); } } T_END; } if (line == NULL) { i_error("Director disconnected unexpectedly"); doveadm_exit_code = EX_TEMPFAIL; } director_disconnect(ctx); }
static int master_connection_input_line(struct master_connection *conn, const char *line) { const char *const *args = t_strsplit_tabescaped(line); struct mail_storage_service_input input; struct mail_storage_service_user *service_user; struct mail_user *user; const char *str, *error; unsigned int max_recent_msgs; int ret; /* <username> <mailbox> <session ID> <max_recent_msgs> [i][o] */ if (str_array_length(args) != 5 || str_to_uint(args[3], &max_recent_msgs) < 0 || args[4][0] == '\0') { i_error("Invalid input from master: %s", line); return -1; } i_zero(&input); input.module = "mail"; input.service = "indexer-worker"; input.username = args[0]; /* if session-id is given, use it as a prefix to a unique session ID. we can't use the session-id directly or stats process will complain about duplicates. (especially LMTP would use the same session-id for multiple users' indexing at the same time.) */ if (args[2][0] != '\0') input.session_id_prefix = args[2]; if (mail_storage_service_lookup_next(conn->storage_service, &input, &service_user, &user, &error) <= 0) { i_error("User %s lookup failed: %s", args[0], error); ret = -1; } else { indexer_worker_refresh_proctitle(user->username, args[1], 0, 0); ret = index_mailbox(conn, user, args[1], max_recent_msgs, args[4]); /* refresh proctitle before a potentially long-running user unref */ indexer_worker_refresh_proctitle(user->username, "(deinit)", 0, 0); mail_user_unref(&user); mail_storage_service_user_unref(&service_user); indexer_worker_refresh_proctitle(NULL, NULL, 0, 0); } str = ret < 0 ? "-1\n" : "100\n"; return write_full(conn->fd, str, strlen(str)); }
static int auth_server_input_cont(struct auth_server_connection *conn, const char *const *args) { struct auth_client_request *request; if (str_array_length(args) < 2) { i_error("BUG: Authentication server sent broken CONT line"); return -1; } if (auth_server_lookup_request(conn, args[0], FALSE, &request) < 0) return -1; auth_client_request_server_input(request, AUTH_REQUEST_STATUS_CONTINUE, args + 1); return 0; }
static void cmd_mailbox_metadata_get_init(struct doveadm_mail_cmd_context *_ctx, const char *const args[]) { struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx; const char *key; if (str_array_length(args) != 2) doveadm_mail_help_name("mailbox metadata get"); cmd_mailbox_metadata_parse_key(args[1], &ctx->key_type, &key); ctx->mailbox = p_strdup(_ctx->pool, args[0]); ctx->key = p_strdup(_ctx->pool, key); doveadm_print_header("value", "value", DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE); }
struct userdb_template * userdb_template_build(pool_t pool, const char *userdb_name, const char *args) { struct userdb_template *tmpl; const char *const *tmp, *key, *value, *nonull_value; uid_t uid; gid_t gid; tmpl = p_new(pool, struct userdb_template, 1); tmp = t_strsplit_spaces(args, " "); p_array_init(&tmpl->args, pool, str_array_length(tmp)); for (; *tmp != NULL; tmp++) { value = strchr(*tmp, '='); if (value == NULL) key = *tmp; else key = t_strdup_until(*tmp, value++); nonull_value = value == NULL ? "" : value; if (strcasecmp(key, "uid") == 0) { uid = userdb_parse_uid(NULL, nonull_value); if (uid == (uid_t)-1) { i_fatal("%s userdb: Invalid uid: %s", userdb_name, nonull_value); } value = dec2str(uid); } else if (strcasecmp(key, "gid") == 0) { gid = userdb_parse_gid(NULL, nonull_value); if (gid == (gid_t)-1) { i_fatal("%s userdb: Invalid gid: %s", userdb_name, nonull_value); } value = dec2str(gid); } else if (*key == '\0') { i_fatal("%s userdb: Empty key (=%s)", userdb_name, nonull_value); } key = p_strdup(pool, key); value = p_strdup(pool, value); array_append(&tmpl->args, &key, 1); array_append(&tmpl->args, &value, 1); } return tmpl; }
static bool master_input_request(struct auth_master_connection *conn, const char *args) { struct auth_client_connection *client_conn; const char *const *list, *const *params; unsigned int id, client_pid, client_id; uint8_t cookie[MASTER_AUTH_COOKIE_SIZE]; buffer_t buf; /* <id> <client-pid> <client-id> <cookie> [<parameters>] */ list = t_strsplit_tab(args); if (str_array_length(list) < 4 || str_to_uint(list[0], &id) < 0 || str_to_uint(list[1], &client_pid) < 0 || str_to_uint(list[2], &client_id) < 0) { i_error("BUG: Master sent broken REQUEST"); return FALSE; } buffer_create_from_data(&buf, cookie, sizeof(cookie)); if (hex_to_binary(list[3], &buf) < 0) { i_error("BUG: Master sent broken REQUEST cookie"); return FALSE; } params = list + 4; client_conn = auth_client_connection_lookup(client_pid); if (client_conn == NULL) { i_error("Master requested auth for nonexistent client %u", client_pid); o_stream_nsend_str(conn->output, t_strdup_printf("FAIL\t%u\n", id)); } else if (memcmp(client_conn->cookie, cookie, sizeof(cookie)) != 0) { i_error("Master requested auth for client %u with invalid cookie", client_pid); o_stream_nsend_str(conn->output, t_strdup_printf("FAIL\t%u\n", id)); } else if (!auth_request_handler_master_request( client_conn->request_handler, conn, id, client_id, params)) { i_error("Master requested auth for non-login client %u", client_pid); o_stream_nsend_str(conn->output, t_strdup_printf("FAIL\t%u\n", id)); } return TRUE; }
struct dsync_message * dsync_message_dup(pool_t pool, const struct dsync_message *msg) { struct dsync_message *dest; const char **keywords; unsigned int i, count; dest = p_new(pool, struct dsync_message, 1); *dest = *msg; dest->guid = p_strdup(pool, msg->guid); if (msg->keywords != NULL) { count = str_array_length(msg->keywords); keywords = p_new(pool, const char *, count+1); for (i = 0; i < count; i++) keywords[i] = p_strdup(pool, msg->keywords[i]); dest->keywords = keywords; }
struct acl_backend * acl_backend_init(const char *data, struct mailbox_list *list, const char *acl_username, const char *const *groups, bool owner) { struct mail_user *user = mailbox_list_get_user(list); struct acl_backend *backend; unsigned int i, group_count; if (user->mail_debug) { i_debug("acl: initializing backend with data: %s", data); i_debug("acl: acl username = %s", acl_username); i_debug("acl: owner = %d", owner ? 1 : 0); } group_count = str_array_length(groups); if (strncmp(data, "vfile:", 6) == 0) data += 6; else if (strcmp(data, "vfile") == 0) data = ""; else i_fatal("Unknown ACL backend: %s", t_strcut(data, ':')); backend = acl_backend_vfile.alloc(); backend->debug = user->mail_debug; backend->v = acl_backend_vfile; backend->list = list; backend->username = p_strdup(backend->pool, acl_username); backend->owner = owner; backend->globals_only = mail_user_plugin_getenv_bool(user, "acl_globals_only"); if (group_count > 0) { backend->group_count = group_count; backend->groups = p_new(backend->pool, const char *, group_count); for (i = 0; i < group_count; i++) { backend->groups[i] = p_strdup(backend->pool, groups[i]); if (user->mail_debug) i_debug("acl: group added: %s", groups[i]); } i_qsort(backend->groups, group_count, sizeof(const char *), i_strcmp_p); }
static struct imap_match_glob * imap_match_init_multiple_real(pool_t pool, const char *const *patterns, bool inboxcase, char separator) { struct imap_match_glob *glob; struct imap_match_pattern *match_patterns; unsigned int i, len, pos, patterns_count, patterns_data_len = 0; patterns_count = str_array_length(patterns); match_patterns = p_new(pool, struct imap_match_pattern, patterns_count + 1); /* compress the patterns */ for (i = 0; i < patterns_count; i++) { match_patterns[i].pattern = pattern_compress(patterns[i]); match_patterns[i].inboxcase = inboxcase && pattern_is_inboxcase(match_patterns[i].pattern, separator); patterns_data_len += strlen(match_patterns[i].pattern) + 1; } patterns_count = i; /* now we know how much memory we need */ glob = p_malloc(pool, sizeof(struct imap_match_glob) + patterns_data_len); glob->pool = pool; glob->sep = separator; /* copy pattern strings to our allocated memory */ for (i = 0, pos = 0; i < patterns_count; i++) { len = strlen(match_patterns[i].pattern) + 1; i_assert(pos + len <= patterns_data_len); /* @UNSAFE */ memcpy(glob->patterns_data + pos, match_patterns[i].pattern, len); match_patterns[i].pattern = glob->patterns_data + pos; pos += len; } glob->patterns = match_patterns; return glob; }
static int client_input_remove(struct doveadm_connection *client, const char *const *args) { struct replicator_user *user; /* <username> */ if (str_array_length(args) != 1) { i_error("%s: REMOVE: Invalid parameters", client->conn.name); return -1; } user = replicator_queue_lookup(client->queue, args[0]); if (user == NULL) o_stream_send_str(client->conn.output, "-User not found\n"); else { replicator_queue_remove(client->queue, &user); o_stream_send_str(client->conn.output, "+\n"); } return 0; }
int dsync_deserializer_init(const char *name, const char *const *required_fields, const char *header_line, struct dsync_deserializer **deserializer_r, const char **error_r) { struct dsync_deserializer *deserializer; const char **dup_required_fields; unsigned int i, required_count; pool_t pool; *deserializer_r = NULL; pool = pool_alloconly_create("dsync deserializer", 1024); deserializer = p_new(pool, struct dsync_deserializer, 1); deserializer->pool = pool; deserializer->name = p_strdup(pool, name); deserializer->keys = (void *)p_strsplit_tabescaped(pool, header_line); deserializer->required_field_count = required_count = required_fields == NULL ? 0 : str_array_length(required_fields); dup_required_fields = p_new(pool, const char *, required_count + 1); deserializer->required_field_indexes = p_new(pool, unsigned int, required_count + 1); for (i = 0; i < required_count; i++) { dup_required_fields[i] = p_strdup(pool, required_fields[i]); if (!field_find(deserializer->keys, required_fields[i], &deserializer->required_field_indexes[i])) { *error_r = t_strdup_printf( "Header missing required field %s", required_fields[i]); pool_unref(&pool); return -1; } } deserializer->required_fields = dup_required_fields; *deserializer_r = deserializer; return 0; }
static void stats_metrics_add_set(struct stats_metrics *metrics, const struct stats_metric_settings *set) { struct event_filter_query query; struct metric *metric; const char *const *fields; metric = p_new(metrics->pool, struct metric, 1); metric->name = p_strdup(metrics->pool, set->name); metric->duration_stats = stats_dist_init(); fields = t_strsplit_spaces(set->fields, " "); metric->fields_count = str_array_length(fields); if (metric->fields_count > 0) { metric->fields = p_new(metrics->pool, struct metric_field, metric->fields_count); for (unsigned int i = 0; i < metric->fields_count; i++) { metric->fields[i].field_key = p_strdup(metrics->pool, fields[i]); metric->fields[i].stats = stats_dist_init(); } }
static int master_connection_input_line(struct master_connection *conn, const char *line) { const char *const *args = t_strsplit_tabescaped(line); struct mail_storage_service_input input; struct mail_storage_service_user *service_user; struct mail_user *user; const char *str, *error; unsigned int max_recent_msgs; int ret; /* <username> <mailbox> <max_recent_msgs> [i][o] */ if (str_array_length(args) != 4 || str_to_uint(args[2], &max_recent_msgs) < 0 || args[3][0] == '\0') { i_error("Invalid input from master: %s", line); return -1; } memset(&input, 0, sizeof(input)); input.module = "mail"; input.service = "indexer-worker"; input.username = args[0]; if (mail_storage_service_lookup_next(conn->storage_service, &input, &service_user, &user, &error) <= 0) { i_error("User %s lookup failed: %s", args[0], error); ret = -1; } else { indexer_worker_refresh_proctitle(user->username, args[1], 0, 0); ret = index_mailbox(conn, user, args[1], max_recent_msgs, args[3]); indexer_worker_refresh_proctitle(NULL, NULL, 0, 0); mail_user_unref(&user); mail_storage_service_user_free(&service_user); } str = ret < 0 ? "-1\n" : "100\n"; return write_full(conn->fd, str, strlen(str)); }
static int client_input_replicate(struct doveadm_connection *client, const char *const *args) { struct replicator_queue_iter *iter; struct replicator_user *user; const char *usermask; enum replication_priority priority; unsigned int match_count; /* <priority> <username>|<mask> */ if (str_array_length(args) != 2) { i_error("%s: REPLICATE: Invalid parameters", client->conn.name); return -1; } if (replication_priority_parse(args[0], &priority) < 0) { o_stream_send_str(client->conn.output, "-Invalid priority\n"); return 0; } usermask = args[1]; if (strchr(usermask, '*') == NULL && strchr(usermask, '?') == NULL) { replicator_queue_add(client->queue, usermask, priority); o_stream_send_str(client->conn.output, "+1\n"); return 0; } match_count = 0; iter = replicator_queue_iter_init(client->queue); while ((user = replicator_queue_iter_next(iter)) != NULL) { if (!wildcard_match(user->username, usermask)) continue; replicator_queue_add(client->queue, user->username, priority); match_count++; } replicator_queue_iter_deinit(&iter); o_stream_send_str(client->conn.output, t_strdup_printf("+%u\n", match_count)); return 0; }
static int notify_connection_input_line(struct notify_connection *conn, const char *line) { struct notify_sync_request *request; const char *const *args; enum replication_priority priority; unsigned int id; /* U \t <username> \t <priority> [\t <sync id>] */ args = t_strsplit_tabescaped(line); if (str_array_length(args) < 2) { i_error("notify client sent invalid input: %s", line); return -1; } if (strcmp(args[0], "U") != 0) { i_error("notify client sent unknown command: %s", args[0]); return -1; } if (replication_priority_parse(args[2], &priority) < 0) { i_error("notify client sent invalid priority: %s", args[2]); return -1; } if (priority != REPLICATION_PRIORITY_SYNC) (void)replicator_queue_add(conn->queue, args[1], priority); else if (args[3] == NULL || str_to_uint(args[3], &id) < 0) { i_error("notify client sent invalid sync id: %s", line); return -1; } else { request = i_new(struct notify_sync_request, 1); request->conn = conn; request->id = id; notify_connection_ref(conn); replicator_queue_add_sync(conn->queue, args[1], notify_sync_callback, request); } return 0; }
struct passdb_template *passdb_template_build(pool_t pool, const char *args) { struct passdb_template *tmpl; const char *const *tmp, *key, *value; tmpl = p_new(pool, struct passdb_template, 1); tmp = t_strsplit_spaces(args, " "); p_array_init(&tmpl->args, pool, str_array_length(tmp)); for (; *tmp != NULL; tmp++) { value = strchr(*tmp, '='); if (value == NULL) key = *tmp; else key = t_strdup_until(*tmp, value++); key = p_strdup(pool, key); value = p_strdup(pool, value); array_append(&tmpl->args, &key, 1); array_append(&tmpl->args, &value, 1); } return tmpl; }
static int notify_input_line(struct notify_connection *conn, const char *line) { const char *const *args; enum replication_priority priority; /* <username> \t <priority> */ args = t_strsplit_tabescaped(line); if (str_array_length(args) < 2) { i_error("Client sent invalid input"); return -1; } if (replication_priority_parse(args[1], &priority) < 0) { i_error("Client sent invalid priority: %s", args[1]); return -1; } if (priority != REPLICATION_PRIORITY_SYNC) replicator_connection_notify(replicator, args[0], priority); else { conn->refcount++; replicator_connection_notify_sync(replicator, args[0], conn); } return 0; }