bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#include "lib.h"
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen#include "str.h"
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen#include "strescape.h"
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen#include "istream.h"
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen#include "write-full.h"
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#include "doveadm.h"
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen#include "doveadm-print.h"
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#include <unistd.h>
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#include <fcntl.h>
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#include <signal.h>
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen#define MASTER_PID_FILE_NAME "master.pid"
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenstatic bool pid_file_read(const char *path, pid_t *pid_r)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen{
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen char buf[32];
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen int fd;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen ssize_t ret;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen bool found;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen fd = open(path, O_RDONLY);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (fd == -1) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (errno == ENOENT)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen return FALSE;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_fatal("open(%s) failed: %m", path);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
2a325b952fe47346d76221d2c07a3fe02faf8800Timo Sirainen ret = read(fd, buf, sizeof(buf)-1);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (ret <= 0) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (ret == 0)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_error("Empty PID file in %s", path);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen else
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_fatal("read(%s) failed: %m", path);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen found = FALSE;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen } else {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (buf[ret-1] == '\n')
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen ret--;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen buf[ret] = '\0';
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (str_to_pid(buf, pid_r) < 0)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen found = FALSE;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen else {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen found = !(*pid_r == getpid() ||
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen (kill(*pid_r, 0) < 0 && errno == ESRCH));
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
4307c886579381dbb1897ea1388ae6978c96f560Timo Sirainen i_close_fd(&fd);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen return found;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen}
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainenvoid doveadm_master_send_signal(int signo)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen{
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen const char *pidfile_path;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen unsigned int i;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen pid_t pid;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen pidfile_path = t_strconcat(doveadm_settings->base_dir,
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen "/"MASTER_PID_FILE_NAME, NULL);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (!pid_file_read(pidfile_path, &pid))
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_fatal("Dovecot is not running (read from %s)", pidfile_path);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (kill(pid, signo) < 0)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_fatal("kill(%s, %d) failed: %m", dec2str(pid), signo);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (signo == SIGTERM) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen /* wait for a while for the process to die */
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen usleep(1000);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen for (i = 0; i < 30; i++) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (kill(pid, 0) < 0) {
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen if (errno != ESRCH)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen i_error("kill() failed: %m");
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen break;
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen usleep(100000);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen }
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen}
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenstatic void cmd_stop(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen{
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen doveadm_master_send_signal(SIGTERM);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen}
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainenstatic void cmd_reload(int argc ATTR_UNUSED, char *argv[] ATTR_UNUSED)
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen{
bf333c7645b8ddb6eedd6834db2fd908888793e1Timo Sirainen doveadm_master_send_signal(SIGHUP);
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen}
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainenstatic struct istream *master_service_send_cmd(const char *cmd)
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen{
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen const char *path;
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen path = t_strconcat(doveadm_settings->base_dir, "/master", NULL);
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen int fd = net_connect_unix(path);
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen if (fd == -1)
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen i_fatal("net_connect_unix(%s) failed: %m", path);
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen net_set_nonblock(fd, FALSE);
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen const char *str =
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen t_strdup_printf("VERSION\tmaster-client\t1\t0\n%s\n", cmd);
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen if (write_full(fd, str, strlen(str)) < 0)
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen i_error("write(%s) failed: %m", path);
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen return i_stream_create_fd_autoclose(&fd, IO_BLOCK_SIZE);
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen}
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainenstatic struct istream *
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainenmaster_service_send_cmd_with_args(const char *cmd, const char *const *args)
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen{
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen string_t *str = t_str_new(128);
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen str_append(str, cmd);
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen if (args != NULL) {
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen for (unsigned int i = 0; args[i] != NULL; i++) {
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen str_append_c(str, '\t');
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen str_append_tabescaped(str, args[i]);
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen }
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen }
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen return master_service_send_cmd(str_c(str));
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen}
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen
de41dbb482990a4be10ca9033cf881a850ccdc50Timo Sirainenstatic void cmd_service_stop(struct doveadm_cmd_context *cctx)
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen{
de41dbb482990a4be10ca9033cf881a850ccdc50Timo Sirainen const char *line, *const *services;
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen
de41dbb482990a4be10ca9033cf881a850ccdc50Timo Sirainen if (!doveadm_cmd_param_array(cctx, "service", &services))
de41dbb482990a4be10ca9033cf881a850ccdc50Timo Sirainen i_fatal("service parameter missing");
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen struct istream *input =
27bb267255b36d34c638c34a1ade611962f00772Timo Sirainen master_service_send_cmd_with_args("STOP", services);
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen alarm(5);
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen if (i_stream_read_next_line(input) == NULL ||
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen (line = i_stream_read_next_line(input)) == NULL) {
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen i_error("read(%s) failed: %s", i_stream_get_name(input),
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen i_stream_get_error(input));
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen doveadm_exit_code = EX_TEMPFAIL;
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen } else if (line[0] == '-') {
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen doveadm_exit_code = DOVEADM_EX_NOTFOUND;
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen i_error("%s", line+1);
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen } else if (line[0] != '+') {
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen i_error("Unexpected input from %s: %s",
7237f2f0a577413e12662228ee2039425fd2f5b0Timo Sirainen i_stream_get_name(input), line);
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen doveadm_exit_code = EX_TEMPFAIL;
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen }
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen alarm(0);
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen i_stream_destroy(&input);
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen}
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainenstatic void cmd_service_status(struct doveadm_cmd_context *cctx)
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen{
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen const char *line, *const *services;
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen if (!doveadm_cmd_param_array(cctx, "service", &services))
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen services = NULL;
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen struct istream *input = master_service_send_cmd("SERVICE-STATUS");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen
a4a7440a1033203c48d5f0174b3d85514b79f3a0Timo Sirainen doveadm_print_init(DOVEADM_PRINT_TYPE_PAGER);
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print_header_simple("name");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print_header_simple("process_count");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print_header_simple("process_avail");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print_header_simple("process_limit");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print_header_simple("client_limit");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print_header_simple("throttle_secs");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print_header_simple("exit_failure_last");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print_header_simple("exit_failures_in_sec");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print_header_simple("last_drop_warning");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print_header_simple("listen_pending");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print_header_simple("listening");
77a41c18e6c37ea9d88a300173672746e29fe61bTimo Sirainen doveadm_print_header_simple("doveadm_stop");
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen alarm(5);
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen while ((line = i_stream_read_next_line(input)) != NULL) {
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen if (line[0] == '\0')
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen break;
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen T_BEGIN {
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen const char *const *args = t_strsplit_tabescaped(line);
77a41c18e6c37ea9d88a300173672746e29fe61bTimo Sirainen if (str_array_length(args) >= 12 &&
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen (services == NULL ||
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen str_array_find(services, args[0]))) {
77a41c18e6c37ea9d88a300173672746e29fe61bTimo Sirainen for (unsigned int i = 0; i < 12; i++)
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_print(args[i]);
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen }
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen } T_END;
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen }
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen if (line == NULL) {
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen i_error("read(%s) failed: %s", i_stream_get_name(input),
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen i_stream_get_error(input));
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen doveadm_exit_code = EX_TEMPFAIL;
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen }
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen alarm(0);
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen i_stream_destroy(&input);
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen}
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainenstatic void cmd_process_status(struct doveadm_cmd_context *cctx)
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen{
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen const char *line, *const *services;
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen if (!doveadm_cmd_param_array(cctx, "service", &services))
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen services = NULL;
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen struct istream *input =
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen master_service_send_cmd_with_args("PROCESS-STATUS", services);
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen doveadm_print_header_simple("name");
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen doveadm_print_header_simple("pid");
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen doveadm_print_header_simple("available_count");
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen doveadm_print_header_simple("total_count");
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen doveadm_print_header_simple("idle_start");
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen doveadm_print_header_simple("last_status_update");
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen doveadm_print_header_simple("last_kill_sent");
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen alarm(5);
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen while ((line = i_stream_read_next_line(input)) != NULL) {
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen if (line[0] == '\0')
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen break;
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen T_BEGIN {
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen const char *const *args = t_strsplit_tabescaped(line);
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen if (str_array_length(args) >= 7) {
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen for (unsigned int i = 0; i < 7; i++)
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen doveadm_print(args[i]);
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen }
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen } T_END;
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen }
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen if (line == NULL) {
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen i_error("read(%s) failed: %s", i_stream_get_name(input),
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen i_stream_get_error(input));
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen doveadm_exit_code = EX_TEMPFAIL;
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen }
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen alarm(0);
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen i_stream_destroy(&input);
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen}
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen
68cc278710182485b6c09e9a9ff8db90a727f343Aki Tuomistruct doveadm_cmd_ver2 doveadm_cmd_stop_ver2 = {
68cc278710182485b6c09e9a9ff8db90a727f343Aki Tuomi .old_cmd = cmd_stop,
68cc278710182485b6c09e9a9ff8db90a727f343Aki Tuomi .name = "stop",
68cc278710182485b6c09e9a9ff8db90a727f343Aki Tuomi .usage = "",
68cc278710182485b6c09e9a9ff8db90a727f343Aki TuomiDOVEADM_CMD_PARAMS_START
68cc278710182485b6c09e9a9ff8db90a727f343Aki TuomiDOVEADM_CMD_PARAMS_END
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen};
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen
68cc278710182485b6c09e9a9ff8db90a727f343Aki Tuomistruct doveadm_cmd_ver2 doveadm_cmd_reload_ver2 = {
68cc278710182485b6c09e9a9ff8db90a727f343Aki Tuomi .old_cmd = cmd_reload,
68cc278710182485b6c09e9a9ff8db90a727f343Aki Tuomi .name = "reload",
68cc278710182485b6c09e9a9ff8db90a727f343Aki Tuomi .usage = "",
68cc278710182485b6c09e9a9ff8db90a727f343Aki TuomiDOVEADM_CMD_PARAMS_START
68cc278710182485b6c09e9a9ff8db90a727f343Aki TuomiDOVEADM_CMD_PARAMS_END
169b1488b6eea7a968021afa4f929b2e26d75d98Timo Sirainen};
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainenstruct doveadm_cmd_ver2 doveadm_cmd_service_stop_ver2 = {
de41dbb482990a4be10ca9033cf881a850ccdc50Timo Sirainen .cmd = cmd_service_stop,
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen .name = "service stop",
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen .usage = "<service> [<service> [...]]",
c7713320cd35e77543f1bdc7229988a160dae322Timo SirainenDOVEADM_CMD_PARAMS_START
c7713320cd35e77543f1bdc7229988a160dae322Timo SirainenDOVEADM_CMD_PARAM('\0', "service", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL)
c7713320cd35e77543f1bdc7229988a160dae322Timo SirainenDOVEADM_CMD_PARAMS_END
c7713320cd35e77543f1bdc7229988a160dae322Timo Sirainen};
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainenstruct doveadm_cmd_ver2 doveadm_cmd_service_status_ver2 = {
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen .cmd = cmd_service_status,
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen .name = "service status",
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen .usage = "[<service> [...]]",
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo SirainenDOVEADM_CMD_PARAMS_START
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo SirainenDOVEADM_CMD_PARAM('\0', "service", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL)
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo SirainenDOVEADM_CMD_PARAMS_END
eba7f36feec8d02c4c394e55ff4effd47e33d311Timo Sirainen};
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainenstruct doveadm_cmd_ver2 doveadm_cmd_process_status_ver2 = {
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen .cmd = cmd_process_status,
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen .name = "process status",
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen .usage = "[<service> [...]]",
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo SirainenDOVEADM_CMD_PARAMS_START
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo SirainenDOVEADM_CMD_PARAM('\0', "service", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONAL)
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo SirainenDOVEADM_CMD_PARAMS_END
d78f1ac9dc0f3e6c64cebe9ee331ec6b3c160e89Timo Sirainen};