Ejemplo n.º 1
0
int
main(int argc, char *argv[])
{
	struct sockaddr_un	 sun;
	struct parse_result	*res;
	struct imsg		 imsg;
	int			 ctl_sock;
	int			 done = 0;
	int			 n, verbose = 0;

	/* parse options */
	if ((res = parse(argc - 1, argv + 1)) == NULL)
		exit(1);

	/* connect to relayd control socket */
	if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		err(1, "socket");

	bzero(&sun, sizeof(sun));
	sun.sun_family = AF_UNIX;
	strlcpy(sun.sun_path, RELAYD_SOCKET, sizeof(sun.sun_path));
 reconnect:
	if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
		/* Keep retrying if running in monitor mode */
		if (res->action == MONITOR &&
		    (errno == ENOENT || errno == ECONNREFUSED)) {
			usleep(100);
			goto reconnect;
		}
		err(1, "connect: %s", RELAYD_SOCKET);
	}

	if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
		err(1, NULL);
	imsg_init(ibuf, ctl_sock);
	done = 0;

	/* process user request */
	switch (res->action) {
	case NONE:
		usage();
		/* not reached */
	case SHOW_SUM:
	case SHOW_HOSTS:
	case SHOW_RDRS:
	case SHOW_RELAYS:
	case SHOW_ROUTERS:
		imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0);
		printf("%-4s\t%-8s\t%-24s\t%-7s\tStatus\n",
		    "Id", "Type", "Name", "Avlblty");
		break;
	case SHOW_SESSIONS:
		imsg_compose(ibuf, IMSG_CTL_SESSION, 0, 0, -1, NULL, 0);
		break;
	case RDR_ENABLE:
		imsg_compose(ibuf, IMSG_CTL_RDR_ENABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case RDR_DISABLE:
		imsg_compose(ibuf, IMSG_CTL_RDR_DISABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case TABLE_ENABLE:
		imsg_compose(ibuf, IMSG_CTL_TABLE_ENABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case TABLE_DISABLE:
		imsg_compose(ibuf, IMSG_CTL_TABLE_DISABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case HOST_ENABLE:
		imsg_compose(ibuf, IMSG_CTL_HOST_ENABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case HOST_DISABLE:
		imsg_compose(ibuf, IMSG_CTL_HOST_DISABLE, 0, 0, -1,
		    &res->id, sizeof(res->id));
		break;
	case SHUTDOWN:
		imsg_compose(ibuf, IMSG_CTL_SHUTDOWN, 0, 0, -1, NULL, 0);
		break;
	case POLL:
		imsg_compose(ibuf, IMSG_CTL_POLL, 0, 0, -1, NULL, 0);
		break;
	case LOAD:
		imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1,
		    res->path, strlen(res->path));
		done = 1;
		break;
	case RELOAD:
		imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
		done = 1;
		break;
	case MONITOR:
		imsg_compose(ibuf, IMSG_CTL_NOTIFY, 0, 0, -1, NULL, 0);
		break;
	case LOG_VERBOSE:
		verbose = 2;
		/* FALLTHROUGH */
	case LOG_BRIEF:
		imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1,
		    &verbose, sizeof(verbose));
		printf("logging request sent.\n");
		done = 1;
		break;
	}

	while (ibuf->w.queued)
		if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN)
			err(1, "write error");

	while (!done) {
		if ((n = imsg_read(ibuf)) == -1)
			errx(1, "imsg_read error");
		if (n == 0)
			errx(1, "pipe closed");

		while (!done) {
			if ((n = imsg_get(ibuf, &imsg)) == -1)
				errx(1, "imsg_get error");
			if (n == 0)
				break;
			switch (res->action) {
			case SHOW_SUM:
			case SHOW_HOSTS:
			case SHOW_RDRS:
			case SHOW_RELAYS:
			case SHOW_ROUTERS:
				done = show_summary_msg(&imsg, res->action);
				break;
			case SHOW_SESSIONS:
				done = show_session_msg(&imsg);
				break;
			case RDR_DISABLE:
			case RDR_ENABLE:
			case TABLE_DISABLE:
			case TABLE_ENABLE:
			case HOST_DISABLE:
			case HOST_ENABLE:
			case POLL:
			case SHUTDOWN:
				done = show_command_output(&imsg);
				break;
			case NONE:
			case LOG_VERBOSE:
			case LOG_BRIEF:
			case RELOAD:
			case LOAD:
				break;
			case MONITOR:
				done = monitor(&imsg);
				break;
			}
			imsg_free(&imsg);
		}
	}
	close(ctl_sock);
	free(ibuf);

	return (error ? 1 : 0);
}
Ejemplo n.º 2
0
int
main(int argc, char *argv[])
{
	struct sockaddr_un	sun;
	struct parse_result	*res = NULL;
	struct imsg		imsg;
	struct smtpd		smtpd;
	int			ctl_sock;
	int			done = 0;
	int			n, verbose = 0;

	/* parse options */
	if (strcmp(__progname, "sendmail") == 0 || strcmp(__progname, "send-mail") == 0)
		sendmail = 1;
	else if (strcmp(__progname, "mailq") == 0) {
		if (geteuid())
			errx(1, "need root privileges");
		setup_env(&smtpd);
		show_queue(0);
		return 0;
	} else if (strcmp(__progname, "smtpctl") == 0) {

		/* check for root privileges */
		if (geteuid())
			errx(1, "need root privileges");

		setup_env(&smtpd);

		if ((res = parse(argc - 1, argv + 1)) == NULL)
			exit(1);

		/* handle "disconnected" commands */
		switch (res->action) {
		case SHOW_QUEUE:
			show_queue(0);
			break;
		case SHOW_RUNQUEUE:
			break;
		default:
			goto connected;
		}
		return 0;
	} else
		errx(1, "unsupported mode");

connected:
	/* connect to smtpd control socket */
	if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		err(1, "socket");

	bzero(&sun, sizeof(sun));
	sun.sun_family = AF_UNIX;
	strlcpy(sun.sun_path, SMTPD_SOCKET, sizeof(sun.sun_path));
	if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
		if (sendmail)
			return enqueue_offline(argc, argv);
		err(1, "connect: %s", SMTPD_SOCKET);
	}

	if ((ibuf = calloc(1, sizeof(struct imsgbuf))) == NULL)
		err(1, NULL);
	imsg_init(ibuf, ctl_sock);

	if (sendmail)
		return enqueue(argc, argv);

	/* process user request */
	switch (res->action) {
	case NONE:
		usage();
		/* not reached */

	case SCHEDULE:
	case REMOVE: {
		u_int64_t ulval;
		char *ep;

		errno = 0;
		ulval = strtoull(res->data, &ep, 16);
		if (res->data[0] == '\0' || *ep != '\0')
			errx(1, "invalid msgid/evpid");
		if (errno == ERANGE && ulval == ULLONG_MAX)
			errx(1, "invalid msgid/evpid");
		if (ulval == 0)
			errx(1, "invalid msgid/evpid");

		if (res->action == SCHEDULE)
			imsg_compose(ibuf, IMSG_SCHEDULER_SCHEDULE, 0, 0, -1, &ulval,
			    sizeof(ulval));
		if (res->action == REMOVE)
			imsg_compose(ibuf, IMSG_SCHEDULER_REMOVE, 0, 0, -1, &ulval,
			    sizeof(ulval));
		break;
	}

	case SCHEDULE_ALL: {
		u_int64_t ulval = 0;

		imsg_compose(ibuf, IMSG_SCHEDULER_SCHEDULE, 0, 0, -1, &ulval,
		    sizeof(ulval));
		break;
	}

	case SHUTDOWN:
		imsg_compose(ibuf, IMSG_CTL_SHUTDOWN, 0, 0, -1, NULL, 0);
		break;
	case PAUSE_MDA:
		imsg_compose(ibuf, IMSG_QUEUE_PAUSE_MDA, 0, 0, -1, NULL, 0);
		break;
	case PAUSE_MTA:
		imsg_compose(ibuf, IMSG_QUEUE_PAUSE_MTA, 0, 0, -1, NULL, 0);
		break;
	case PAUSE_SMTP:
		imsg_compose(ibuf, IMSG_SMTP_PAUSE, 0, 0, -1, NULL, 0);
		break;
	case RESUME_MDA:
		imsg_compose(ibuf, IMSG_QUEUE_RESUME_MDA, 0, 0, -1, NULL, 0);
		break;
	case RESUME_MTA:
		imsg_compose(ibuf, IMSG_QUEUE_RESUME_MTA, 0, 0, -1, NULL, 0);
		break;
	case RESUME_SMTP:
		imsg_compose(ibuf, IMSG_SMTP_RESUME, 0, 0, -1, NULL, 0);
		break;
	case SHOW_STATS:
		imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, NULL, 0);
		break;
	case MONITOR:
		/* XXX */
		break;
	case LOG_VERBOSE:
		verbose = 1;
		/* FALLTHROUGH */
	case LOG_BRIEF:
		imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1, &verbose,
		    sizeof(verbose));
		printf("logging request sent.\n");
		done = 1;
		break;
	default:
		errx(1, "unknown request (%d)", res->action);
	}

	while (ibuf->w.queued)
		if (msgbuf_write(&ibuf->w) < 0)
			err(1, "write error");

	while (!done) {
		if ((n = imsg_read(ibuf)) == -1)
			errx(1, "imsg_read error");
		if (n == 0)
			errx(1, "pipe closed");

		while (!done) {
			if ((n = imsg_get(ibuf, &imsg)) == -1)
				errx(1, "imsg_get error");
			if (n == 0)
				break;
			switch(res->action) {
			case REMOVE:
			case SCHEDULE:
			case SCHEDULE_ALL:
			case SHUTDOWN:
			case PAUSE_MDA:
			case PAUSE_MTA:
			case PAUSE_SMTP:
			case RESUME_MDA:
			case RESUME_MTA:
			case RESUME_SMTP:
			case LOG_VERBOSE:
			case LOG_BRIEF:
				done = show_command_output(&imsg);
				break;
			case SHOW_STATS:
				done = show_stats_output(&imsg);
				break;
			case NONE:
				break;
			case MONITOR:
				break;
			default:
				err(1, "unexpected reply (%d)", res->action);
			}
			/* insert imsg replies switch here */

			imsg_free(&imsg);
		}
	}
	close(ctl_sock);
	free(ibuf);

	return (0);
}