示例#1
0
void mail_commands_free_memory(void)
{
	unsigned int diff;

	while (stable_mail_commands_head != NULL) {
		struct mail_command *cmd = stable_mail_commands_head;

		if (cmd->refcount == 0)
			i_assert(cmd->id == 0);
		else if (cmd->refcount == 1 &&
			 (cmd->session->disconnected ||
			  mail_command_is_timed_out(cmd))) {
			/* session was probably lost */
			mail_command_unref(&cmd);
		} else {
			break;
		}
		mail_command_free(stable_mail_commands_head);

		if (global_used_memory < stats_settings->memory_limit ||
		    stable_mail_commands_head == NULL)
			break;

		diff = ioloop_time - stable_mail_commands_head->last_update.tv_sec;
		if (diff < stats_settings->command_min_time)
			break;
	}
}
示例#2
0
void mail_commands_deinit(void)
{
	while (stable_mail_commands_head != NULL) {
		struct mail_command *cmd = stable_mail_commands_head;

		if (cmd->id != 0)
			mail_command_unref(&cmd);
		mail_command_free(stable_mail_commands_head);
	}
}
示例#3
0
static void client_unref_iters(struct client *client)
{
	if (client->mail_cmd_iter != NULL)
		mail_command_unref(&client->mail_cmd_iter);
	if (client->mail_session_iter != NULL)
		mail_session_unref(&client->mail_session_iter);
	if (client->mail_user_iter != NULL)
		mail_user_unref(&client->mail_user_iter);
	if (client->mail_domain_iter != NULL)
		mail_domain_unref(&client->mail_domain_iter);
	if (client->mail_ip_iter != NULL)
		mail_ip_unref(&client->mail_ip_iter);
}
示例#4
0
static int client_export_iter_command(struct client *client)
{
	struct client_export_cmd *cmd = client->cmd_export;
	struct mail_command *command = client->mail_cmd_iter;

	i_assert(cmd->level == MAIL_EXPORT_LEVEL_COMMAND);
	mail_command_unref(&client->mail_cmd_iter);

	if (!cmd->header_sent) {
		o_stream_nsend_str(client->output,
			"cmd\targs\tsession\tuser\tlast_update"MAIL_STATS_HEADER);
		cmd->header_sent = TRUE;
	}

	for (; command != NULL; command = command->stable_next) {
		if (client_is_busy(client))
			break;
		if (!mail_export_filter_match_session(&cmd->filter,
						      command->session))
			continue;

		str_truncate(cmd->str, 0);
		str_append_tabescaped(cmd->str, command->name);
		str_append_c(cmd->str, '\t');
		str_append_tabescaped(cmd->str, command->args);
		str_append_c(cmd->str, '\t');
		T_BEGIN {
			str_append(cmd->str,
				   guid_128_to_string(command->session->guid));
			str_append_c(cmd->str, '\t');
			str_append_tabescaped(cmd->str,
					      command->session->user->name);
		} T_END;
		client_export_timeval(cmd->str, &command->last_update);
		client_export_mail_stats(cmd->str, &command->stats);
		str_append_c(cmd->str, '\n');
		o_stream_nsend(client->output, str_data(cmd->str),
			       str_len(cmd->str));
	}

	if (command != NULL) {
		client->mail_cmd_iter = command;
		mail_command_ref(command);
		return 0;
	}
	return 1;
}
示例#5
0
int mail_command_update_parse(const char *const *args, const char **error_r)
{
	struct mail_session *session;
	struct mail_command *cmd;
	struct stats *new_stats, *diff_stats;
	buffer_t *buf;
	const char *error;
	unsigned int i, cmd_id;
	bool done = FALSE, continued = FALSE;

	/* <session guid> <cmd id> [d] <name> <args> <stats>
	   <session guid> <cmd id> c[d] <stats> */
	if (str_array_length(args) < 3) {
		*error_r = "UPDATE-CMD: Too few parameters";
		return -1;
	}
	if (mail_session_get(args[0], &session, error_r) < 0)
		return -1;

	if (str_to_uint(args[1], &cmd_id) < 0 || cmd_id == 0) {
		*error_r = "UPDATE-CMD: Invalid command id";
		return -1;
	}
	for (i = 0; args[2][i] != '\0'; i++) {
		switch (args[2][i]) {
		case 'd':
			done = TRUE;
			break;
		case 'c':
			continued = TRUE;
			break;
		default:
			*error_r = "UPDATE-CMD: Invalid flags parameter";
			return -1;
		}
	}

	cmd = mail_command_find(session, cmd_id);
	if (!continued) {
		/* new command */
		if (cmd != NULL) {
			*error_r = "UPDATE-CMD: Duplicate new command id";
			return -1;
		}
		if (str_array_length(args) < 5) {
			*error_r = "UPDATE-CMD: Too few parameters";
			return -1;
		}
		cmd = mail_command_add(session, args[3], args[4]);
		cmd->id = cmd_id;

		session->highest_cmd_id =
			I_MAX(session->highest_cmd_id, cmd_id);
		session->num_cmds++;
		session->user->num_cmds++;
		session->user->domain->num_cmds++;
		if (session->ip != NULL)
			session->ip->num_cmds++;
		mail_global_stats.num_cmds++;
		args += 5;
	} else {
		if (cmd == NULL) {
			/* already expired command, ignore */
			i_warning("UPDATE-CMD: Already expired");
			return 0;
		}
		args += 3;
		cmd->last_update = ioloop_timeval;
	}
	buf = t_buffer_create(256);
	if (args[0] == NULL ||
	    base64_decode(args[0], strlen(args[0]), NULL, buf) < 0) {
		*error_r = t_strdup_printf("UPDATE-CMD: Invalid base64 input");
		return -1;
	}

	new_stats = stats_alloc(pool_datastack_create());
	diff_stats = stats_alloc(pool_datastack_create());

	if (!stats_import(buf->data, buf->used, cmd->stats, new_stats, &error)) {
		*error_r = t_strdup_printf("UPDATE-CMD: %s", error);
		return -1;
	}

	if (!stats_diff(cmd->stats, new_stats, diff_stats, &error)) {
		*error_r = t_strdup_printf("UPDATE-CMD: stats shrank: %s", error);
		return -1;
	}
	stats_add(cmd->stats, diff_stats);

	if (done) {
		cmd->id = 0;
		mail_command_unref(&cmd);
	}
	mail_session_refresh(session, NULL);
	return 0;
}