Ejemplo n.º 1
0
static void
stats_top_output_diff(struct top_context *ctx,
		      const struct top_line *line, unsigned int i)
{
	uint64_t prev_num, cur_num;
	double prev_double, cur_double, prev_time, cur_time;
	char numstr[MAX_INT_STRLEN];

	if (str_to_uint64(line->prev_values[i], &prev_num) == 0 &&
	    str_to_uint64(line->cur_values[i], &cur_num) == 0) {
		if (i_snprintf(numstr, sizeof(numstr), "%llu",
			       (unsigned long long)(cur_num - prev_num)) < 0)
			i_unreached();
		doveadm_print(numstr);
	} else if (get_double(line->prev_values[i], &prev_double) == 0 &&
		   get_double(line->cur_values[i], &cur_double) == 0 &&
		   get_double(line->prev_values[ctx->last_update_idx], &prev_time) == 0 &&
		   get_double(line->cur_values[ctx->last_update_idx], &cur_time) == 0) {
		/* %CPU */
		if (i_snprintf(numstr, sizeof(numstr), "%d",
			       (int)((cur_double - prev_double) *
				     (cur_time - prev_time) * 100)) < 0)
			i_unreached();
		doveadm_print(numstr);
	} else {
		doveadm_print(line->cur_values[i]);
	}
}
Ejemplo n.º 2
0
static void cmd_dict_iter(int argc, char *argv[])
{
	struct dict *dict;
	struct dict_iterate_context *iter;
	enum dict_iterate_flags iter_flags = 0;
	const char *key, *value;

	dict = cmd_dict_init_full(&argc, &argv, 1, 0, cmd_dict_iter, &iter_flags);

	doveadm_print_init(DOVEADM_PRINT_TYPE_TAB);
	doveadm_print_header_simple("key");
	if ((iter_flags & DICT_ITERATE_FLAG_NO_VALUE) == 0)
		doveadm_print_header_simple("value");

	iter = dict_iterate_init(dict, argv[0], iter_flags);
	while (dict_iterate(iter, &key, &value)) {
		doveadm_print(key);
		if ((iter_flags & DICT_ITERATE_FLAG_NO_VALUE) == 0)
			doveadm_print(value);
	}
	if (dict_iterate_deinit(&iter) < 0) {
		i_error("dict_iterate_deinit(%s) failed", argv[0]);
		doveadm_exit_code = EX_TEMPFAIL;
	}
	dict_deinit(&dict);
}
static int
cmd_mailbox_metadata_get_run(struct doveadm_mail_cmd_context *_ctx,
			     struct mail_user *user)
{
	struct metadata_cmd_context *ctx = (struct metadata_cmd_context *)_ctx;
	struct mail_namespace *ns;
	struct mailbox *box;
	struct mail_attribute_value value;
	int ret;

	ret = cmd_mailbox_metadata_open_mailbox(ctx, user, "get attribute",
						&ns, &box);
	if (ret != 0)
		return ret;

	ret = mailbox_attribute_get_stream(box, ctx->key_type, ctx->key, &value);
	if (ret < 0) {
		i_error("Failed to get attribute: %s",
			mailbox_get_last_error(box, NULL));
		doveadm_mail_failed_mailbox(_ctx, box);
	} else if (ret == 0) {
		/* not found, print as empty */
		doveadm_print("");
	} else if (value.value_stream != NULL) {
		doveadm_print_istream(value.value_stream);
	} else {
		doveadm_print(value.value);
	}

	mailbox_free(&box);
	return ret;
}
Ejemplo n.º 4
0
static void cmd_instance_list(int argc, char *argv[])
{
	struct master_instance_list *list;
	struct master_instance_list_iter *iter;
	const struct master_instance *inst;
	const char *instance_path, *pidfile_path;
	bool show_config = FALSE;
	int c;

	while ((c = getopt(argc, argv, "c")) > 0) {
		switch (c) {
		case 'c':
			show_config = TRUE;
			break;
		default:
			help(&doveadm_cmd_instance[0]);
		}
	}
	argv += optind;

	if (!show_config) {
		doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
		doveadm_print_header("path", "path", DOVEADM_PRINT_HEADER_FLAG_EXPAND);
		doveadm_print_header_simple("name");
		doveadm_print_header_simple("last used");
		doveadm_print_header_simple("running");
	}

	instance_path = t_strconcat(service_set->state_dir,
				    "/"MASTER_INSTANCE_FNAME, NULL);
	list = master_instance_list_init(instance_path);
	iter = master_instance_list_iterate_init(list);
	while ((inst = master_instance_iterate_list_next(iter)) != NULL) {
		if (argv[0] != NULL && strcmp(argv[0], inst->name) != 0)
			continue;

		if (show_config) {
			printf("%s\n", inst->config_path == NULL ? "" :
			       inst->config_path);
			continue;
		}
		doveadm_print(inst->base_dir);
		doveadm_print(inst->name);
		doveadm_print(unixdate2str(inst->last_used));
		pidfile_path = t_strconcat(inst->base_dir, "/master.pid", NULL);
		if (pid_file_read(pidfile_path))
			doveadm_print("yes");
		else
			doveadm_print("no");
	}
	master_instance_iterate_list_deinit(&iter);
	master_instance_list_deinit(&list);
}
Ejemplo n.º 5
0
static void cmd_quota_get_root(struct quota_root *root)
{
	const char *const *res;
	uint64_t value, limit;
	int ret;

	res = quota_root_get_resources(root);
	for (; *res != NULL; res++) {
		ret = quota_get_resource(root, "", *res, &value, &limit);
		doveadm_print(root->set->name);
		doveadm_print(*res);
		if (ret > 0) {
			doveadm_print_num(value);
			doveadm_print_num(limit);
			if (limit > 0)
				doveadm_print_num(value*100 / limit);
			else
				doveadm_print("0");
		} else if (ret == 0) {
			doveadm_print_num(value);
			doveadm_print("-");
			doveadm_print("0");
		} else {
			doveadm_print("error");
			doveadm_print("error");
			doveadm_print("error");
		}
	}
}
Ejemplo n.º 6
0
static void cmd_acl_get_right(const struct acl_rights *rights)
{
	const char *id = "";
	string_t *str;

	switch (rights->id_type) {
	case ACL_ID_ANYONE:
		id = ACL_ID_NAME_ANYONE;
		break;
	case ACL_ID_AUTHENTICATED:
		id = ACL_ID_NAME_AUTHENTICATED;
		break;
	case ACL_ID_OWNER:
		id = ACL_ID_NAME_OWNER;
		break;
	case ACL_ID_USER:
		id = t_strconcat(ACL_ID_NAME_USER_PREFIX,
				 rights->identifier, NULL);
		break;
	case ACL_ID_GROUP:
		id = t_strconcat(ACL_ID_NAME_GROUP_PREFIX,
				 rights->identifier, NULL);
		break;
	case ACL_ID_GROUP_OVERRIDE:
		id = t_strconcat(ACL_ID_NAME_GROUP_OVERRIDE_PREFIX,
				 rights->identifier, NULL);
		break;
	case ACL_ID_TYPE_COUNT:
		i_unreached();
	}
	doveadm_print(id);

	if (rights->global)
		doveadm_print("global");
	else
		doveadm_print("");

	str = t_str_new(256);
	if (rights->rights != NULL)
		str_append(str, t_strarray_join(rights->rights, " "));
	if (rights->neg_rights != NULL) {
		if (str_len(str) > 0)
			str_append_c(str, ' ');
		str_append_c(str, '-');
		str_append(str, t_strarray_join(rights->neg_rights, " -"));
	}
	doveadm_print(str_c(str));
}
Ejemplo n.º 7
0
static void cmd_proxy_list_callback(enum ipc_client_cmd_state state,
				    const char *data, void *context)
{
	bool *seen_header = context;

	switch (state) {
	case IPC_CLIENT_CMD_STATE_REPLY: {
		const char *const *args = t_strsplit_tabescaped(data);

		if (!*seen_header) {
			cmd_proxy_list_header(args);
			*seen_header = TRUE;
		} else {
			for (; *args != NULL; args++)
				doveadm_print(*args);
		}
		return;
	}
	case IPC_CLIENT_CMD_STATE_OK:
		break;
	case IPC_CLIENT_CMD_STATE_ERROR:
		i_error("LIST-FULL failed: %s", data);
		break;
	}
	io_loop_stop(current_ioloop);
}
Ejemplo n.º 8
0
static void cmd_acl_get_right(const struct acl_rights *rights)
{
	string_t *str;

	doveadm_print(acl_rights_get_id(rights));

	if (rights->global)
		doveadm_print("global");
	else
		doveadm_print("");

	str = t_str_new(256);
	if (rights->rights != NULL)
		str_append(str, t_strarray_join(rights->rights, " "));
	if (rights->neg_rights != NULL) {
		if (str_len(str) > 0)
			str_append_c(str, ' ');
		str_append_c(str, '-');
		str_append(str, t_strarray_join(rights->neg_rights, " -"));
	}
	doveadm_print(str_c(str));
}
Ejemplo n.º 9
0
static void stats_top_output(struct top_context *ctx)
{
	static const char *names[] = {
		"user", "service", "user_cpu", "sys_cpu",
		"", ""
	};
	struct winsize ws;
	struct top_line *const *lines;
	unsigned int i, j, row, maxrow, count, indexes[N_ELEMENTS(names)];

	names[4] = disk_input_field;
	names[5] = disk_output_field;

	/* ANSI clear screen and move cursor to top of screen */
	printf("\x1b[2J\x1b[1;1H"); fflush(stdout);
	doveadm_print_deinit();
	doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);

	doveadm_print_header("USER", "USER", DOVEADM_PRINT_HEADER_FLAG_EXPAND);
	doveadm_print_header_simple("SERVICE");
	doveadm_print_header_simple("%CPU");
	doveadm_print_header_simple("%SYS");
	doveadm_print_header_simple("DISKIN");
	doveadm_print_header_simple("DISKOUT");

	if (!stats_top_round(ctx)) {
		/* no connections yet */
		return;
	}

	for (i = 0; i < N_ELEMENTS(names); i++) {
		if (!stats_header_find(ctx, names[i], &indexes[i]))
			indexes[i] = UINT_MAX;
	}

	if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
		ws.ws_row = 24;
	maxrow = ws.ws_row-1;

	lines = array_get(&ctx->lines, &count);
	for (i = 0, row = 1; row < maxrow && i < count; i++, row++) {
		for (j = 0; j < N_ELEMENTS(names); j++) {
			if (indexes[j] == UINT_MAX)
				doveadm_print("?");
			else
				stats_top_output_diff(ctx, lines[i], indexes[j]);
		}
	}
}
Ejemplo n.º 10
0
status_output(struct status_cmd_context *ctx, struct mailbox *box,
	      const struct mailbox_status *status,
	      const struct mailbox_metadata *metadata)
{
	if (box != NULL)
		doveadm_print(mailbox_get_vname(box));

	if ((ctx->status_items & STATUS_MESSAGES) != 0)
		doveadm_print_num(status->messages);
	if ((ctx->status_items & STATUS_RECENT) != 0)
		doveadm_print_num(status->recent);
	if ((ctx->status_items & STATUS_UIDNEXT) != 0)
		doveadm_print_num(status->uidnext);
	if ((ctx->status_items & STATUS_UIDVALIDITY) != 0)
		doveadm_print_num(status->uidvalidity);
	if ((ctx->status_items & STATUS_UNSEEN) != 0)
		doveadm_print_num(status->unseen);
	if ((ctx->status_items & STATUS_HIGHESTMODSEQ) != 0)
		doveadm_print_num(status->highest_modseq);
	if ((ctx->metadata_items & MAILBOX_METADATA_VIRTUAL_SIZE) != 0)
		doveadm_print_num(metadata->virtual_size);
	if ((ctx->metadata_items & MAILBOX_METADATA_GUID) != 0)
		doveadm_print(guid_128_to_string(metadata->guid));
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
static void cmd_sis_find(int argc, char *argv[])
{
	const char *rootdir, *path, *hash;
	DIR *dir;
	struct dirent *d;
	struct stat st;
	string_t *str;
	unsigned int dir_len, hash_len;

	if (argc < 3 || strlen(argv[2]) < 4)
		help(&doveadm_cmd_sis_find);

	rootdir = argv[1];
	if (stat(rootdir, &st) < 0) {
		if (errno == ENOENT)
			i_fatal("Attachment dir doesn't exist: %s", rootdir);
		i_fatal("stat(%s) failed: %m", rootdir);
	}
	hash = argv[2];
	hash_len = strlen(hash);

	path = sis_get_dir(rootdir, hash);
	str = t_str_new(256);
	str_append(str, path);
	str_append_c(str, '/');
	dir_len = str_len(str);

	dir = opendir(path);
	if (dir == NULL) {
		if (errno == ENOENT)
			return;
		i_fatal("opendir(%s) failed: %m", path);
	}

	doveadm_print_init(DOVEADM_PRINT_TYPE_FLOW);
	doveadm_print_header("path", "path",
			     DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
	while ((d = readdir(dir)) != NULL) {
		if (strncmp(d->d_name, hash, hash_len) == 0) {
			str_truncate(str, dir_len);
			str_append(str, d->d_name);
			doveadm_print(str_c(str));
		}
	}
	if (closedir(dir) < 0)
		i_error("closedir(%s) failed: %m", path);
}
static void server_flush_field(struct server_connection *conn, string_t *str,
			       const unsigned char *data, size_t size)
{
	if (conn->streaming) {
		conn->streaming = FALSE;
		if (size > 0)
			stream_data(str, data, size);
		doveadm_print_stream("", 0);
	} else {
		const char *text;

		str_truncate(str, 0);
		str_append_n(str, data, size);
		text = str_tabunescape(str_c_modifiable(str));
		doveadm_print(text);
	}
}
Ejemplo n.º 14
0
static int
cmd_mailbox_metadata_list_run_iter(struct metadata_cmd_context *ctx,
				   struct mailbox *box,
				   enum mail_attribute_type type)
{
	struct mailbox_attribute_iter *iter;
	const char *key;

	iter = mailbox_attribute_iter_init(box, type, ctx->key);
	while ((key = mailbox_attribute_iter_next(iter)) != NULL)
		doveadm_print(key);
	if (mailbox_attribute_iter_deinit(&iter) < 0) {
		i_error("Mailbox %s: Failed to iterate mailbox attributes: %s",
			mailbox_get_vname(box),
			mailbox_get_last_error(box, NULL));
		return -1;
	}
	return 0;
}
Ejemplo n.º 15
0
static void stats_dump(const char *path, const char *cmd)
{
	struct istream *input;
	const char *const *args;
	unsigned int i;
	int fd;

	fd = doveadm_connect(path);
	net_set_nonblock(fd, FALSE);

	input = i_stream_create_fd(fd, (size_t)-1, TRUE);
	if (write_full(fd, cmd, strlen(cmd)) < 0)
		i_fatal("write(%s) failed: %m", path);

	/* read header */
	args = read_next_line(input);
	if (args == NULL)
		i_fatal("read(%s) unexpectedly disconnected", path);
	if (*args == NULL)
		i_info("no statistics available");
	else {
		for (; *args != NULL; args++)
			doveadm_print_header_simple(*args);

		/* read lines */
		do {
			T_BEGIN {
				args = read_next_line(input);
				if (args != NULL && args[0] == NULL)
					args = NULL;
				if (args != NULL) {
					for (i = 0; args[i] != NULL; i++)
						doveadm_print(args[i]);
				}
			} T_END;
		} while (args != NULL);
	}
	if (input->stream_errno != 0)
		i_fatal("read(%s) failed: %m", path);
	i_stream_destroy(&input);
}
Ejemplo n.º 16
0
static void cmd_dict_get(int argc, char *argv[])
{
	struct dict *dict;
	const char *value;
	int ret;

	dict = cmd_dict_init(&argc, &argv, 1, 0, cmd_dict_get);

	doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
	doveadm_print_header("value", "", DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);

	ret = dict_lookup(dict, pool_datastack_create(), argv[0], &value);
	if (ret < 0) {
		i_error("dict_lookup(%s) failed", argv[0]);
		doveadm_exit_code = EX_TEMPFAIL;
	} else if (ret == 0) {
		i_error("%s doesn't exist", argv[0]);
		doveadm_exit_code = DOVEADM_EX_NOTFOUND;
	} else {
		doveadm_print(value);
	}
	dict_deinit(&dict);
}
Ejemplo n.º 17
0
static int
cmd_dsync_run(struct doveadm_mail_cmd_context *_ctx, struct mail_user *user)
{
	struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx;
	struct dsync_ibc *ibc, *ibc2 = NULL;
	struct dsync_brain *brain;
	struct dsync_brain_settings set;
	enum dsync_brain_flags brain_flags;
	bool remote_errors_logged = FALSE;
	bool changes_during_sync = FALSE;
	int status = 0, ret = 0;

	memset(&set, 0, sizeof(set));
	set.sync_box = ctx->mailbox;
	memcpy(set.sync_box_guid, ctx->mailbox_guid, sizeof(set.sync_box_guid));
	set.lock_timeout_secs = ctx->lock_timeout;
	set.state = ctx->state_input;
	if (array_count(&ctx->exclude_mailboxes) > 0) {
		/* array is NULL-terminated in init() */
		set.exclude_mailboxes = array_idx(&ctx->exclude_mailboxes, 0);
	}
	doveadm_user_init_dsync(user);

	if (ctx->namespace_prefix != NULL) {
		set.sync_ns = mail_namespace_find(user->namespaces,
						  ctx->namespace_prefix);
	}

	if (ctx->run_type == DSYNC_RUN_TYPE_LOCAL)
		dsync_ibc_init_pipe(&ibc, &ibc2);
	else {
		string_t *temp_prefix = t_str_new(64);
		mail_user_set_get_temp_prefix(temp_prefix, user->set);
		ibc = cmd_dsync_icb_stream_init(ctx, ctx->remote_name,
						str_c(temp_prefix));
		if (ctx->fd_err != -1) {
			ctx->io_err = io_add(ctx->fd_err, IO_READ,
					     remote_error_input, ctx);
		}
	}

	brain_flags = DSYNC_BRAIN_FLAG_SEND_MAIL_REQUESTS;
	if (ctx->sync_visible_namespaces)
		brain_flags |= DSYNC_BRAIN_FLAG_SYNC_VISIBLE_NAMESPACES;
	if (ctx->purge_remote)
		brain_flags |= DSYNC_BRAIN_FLAG_PURGE_REMOTE;

	if (ctx->reverse_backup)
		brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_RECV;
	else if (ctx->backup)
		brain_flags |= DSYNC_BRAIN_FLAG_BACKUP_SEND;

	if (ctx->no_mail_sync)
		brain_flags |= DSYNC_BRAIN_FLAG_NO_MAIL_SYNC;
	if (ctx->oneway)
		brain_flags |= DSYNC_BRAIN_FLAG_NO_BACKUP_OVERWRITE;
	if (doveadm_debug)
		brain_flags |= DSYNC_BRAIN_FLAG_DEBUG;

	brain = dsync_brain_master_init(user, ibc, ctx->sync_type,
					brain_flags, &set);

	if (ctx->run_type == DSYNC_RUN_TYPE_LOCAL) {
		if (cmd_dsync_run_local(ctx, user, brain, ibc2,
					&changes_during_sync) < 0)
			ret = -1;
	} else {
		cmd_dsync_run_remote(user);
	}

	if (ctx->state_input != NULL) {
		string_t *state_str = t_str_new(128);
		dsync_brain_get_state(brain, state_str);
		doveadm_print(str_c(state_str));
	}

	if (dsync_brain_has_unexpected_changes(brain) || changes_during_sync) {
		/* don't log a warning when running via doveadm server
		   (e.g. called by replicator) */
		if (ctx->ctx.conn == NULL) {
			i_warning("Mailbox changes caused a desync. "
				  "You may want to run dsync again.");
		}
		ctx->ctx.exit_code = 2;
	}
	if (dsync_brain_deinit(&brain) < 0) {
		ctx->ctx.exit_code = EX_TEMPFAIL;
		ret = -1;
	}
	dsync_ibc_deinit(&ibc);
	if (ibc2 != NULL)
		dsync_ibc_deinit(&ibc2);
	if (ctx->ssl_iostream != NULL)
		ssl_iostream_destroy(&ctx->ssl_iostream);
	if (ctx->ssl_ctx != NULL)
		ssl_iostream_context_deinit(&ctx->ssl_ctx);
	if (ctx->input != NULL)
		i_stream_unref(&ctx->input);
	if (ctx->output != NULL)
		o_stream_unref(&ctx->output);
	if (ctx->fd_in != -1) {
		if (ctx->fd_out != ctx->fd_in)
			i_close_fd(&ctx->fd_out);
		i_close_fd(&ctx->fd_in);
	}
	if (ctx->run_type == DSYNC_RUN_TYPE_CMD)
		cmd_dsync_wait_remote(ctx, &status);

	/* print any final errors after the process has died. not closing
	   stdin/stdout before wait() may cause the process to hang, but stderr
	   shouldn't (at least with ssh) and we need stderr to be open to be
	   able to print the final errors */
	if (ctx->err_stream != NULL) {
		remote_error_input(ctx);
		remote_errors_logged = ctx->err_stream->v_offset > 0;
		i_stream_destroy(&ctx->err_stream);
	}
	if (ctx->run_type == DSYNC_RUN_TYPE_CMD)
		cmd_dsync_log_remote_status(status, remote_errors_logged);
	if (ctx->io_err != NULL)
		io_remove(&ctx->io_err);
	if (ctx->fd_err != -1)
		i_close_fd(&ctx->fd_err);

	return ret;
}