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 replication_add_users(struct replicator_queue *queue) { struct auth_master_connection *auth_conn; struct auth_master_user_list_ctx *ctx; struct auth_user_info user_info; struct replicator_user *user; const char *path, *username; auth_conn = auth_master_init(set->auth_socket_path, AUTH_MASTER_FLAG_NO_IDLE_TIMEOUT); memset(&user_info, 0, sizeof(user_info)); user_info.service = REPLICATOR_AUTH_SERVICE_NAME; /* add all users into replication queue, so that we can start doing full syncs for everyone whose state can't be found */ ctx = auth_master_user_list_init(auth_conn, "", &user_info); while ((username = auth_master_user_list_next(ctx)) != NULL) { user = replicator_queue_add(queue, username, REPLICATION_PRIORITY_NONE); user->last_update = 0; } if (auth_master_user_list_deinit(&ctx) < 0) i_error("listing users failed, can't replicate existing data"); auth_master_deinit(&auth_conn); /* add updates from replicator db, if it exists */ path = t_strconcat(service_set->state_dir, "/"REPLICATOR_DB_FNAME, NULL); (void)replicator_queue_import(queue, path); }
void replicator_queue_add_auth_users(struct replicator_queue *queue, const char *auth_socket_path, const char *usermask, time_t last_update) { struct auth_master_connection *auth_conn; struct auth_master_user_list_ctx *ctx; struct auth_user_info user_info; struct replicator_user *user; const char *username; auth_conn = auth_master_init(auth_socket_path, AUTH_MASTER_FLAG_NO_IDLE_TIMEOUT); memset(&user_info, 0, sizeof(user_info)); user_info.service = REPLICATOR_AUTH_SERVICE_NAME; /* add all users into replication queue, so that we can start doing full syncs for everyone whose state can't be found */ ctx = auth_master_user_list_init(auth_conn, usermask, &user_info); while ((username = auth_master_user_list_next(ctx)) != NULL) { user = replicator_queue_add(queue, username, REPLICATION_PRIORITY_NONE); user->last_update = last_update; } if (auth_master_user_list_deinit(&ctx) < 0) i_error("listing users failed, can't replicate existing data"); auth_master_deinit(&auth_conn); }
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; }