コード例 #1
0
ファイル: queue_proc.c プロジェクト: nmandery/deb-opensmtpd
static int
queue_proc_init(struct passwd *pw, int server, const char *conf)
{
	uint32_t	version;
	int		fd;

	fd = fork_proc_backend("queue", conf, "queue-proc");
	if (fd == -1)
		fatalx("queue-proc: exiting");

	imsg_init(&ibuf, fd);

	version = PROC_QUEUE_API_VERSION;
	imsg_compose(&ibuf, PROC_QUEUE_INIT, 0, 0, -1,
	    &version, sizeof(version));

	queue_api_on_close(queue_proc_close);
	queue_api_on_message_create(queue_proc_message_create);
	queue_api_on_message_commit(queue_proc_message_commit);
	queue_api_on_message_delete(queue_proc_message_delete);
	queue_api_on_message_fd_r(queue_proc_message_fd_r);
	queue_api_on_message_corrupt(queue_proc_message_corrupt);
	queue_api_on_envelope_create(queue_proc_envelope_create);
	queue_api_on_envelope_delete(queue_proc_envelope_delete);
	queue_api_on_envelope_update(queue_proc_envelope_update);
	queue_api_on_envelope_load(queue_proc_envelope_load);
	queue_api_on_envelope_walk(queue_proc_envelope_walk);

	queue_proc_call();
	queue_proc_end();

	return (1);
}
コード例 #2
0
ファイル: table_proc.c プロジェクト: nmandery/deb-opensmtpd
static void *
table_proc_open(struct table *table)
{
	struct table_proc_priv	*priv;
	struct table_open_params op;
	int			 fd;

	priv = xcalloc(1, sizeof(*priv), "table_proc_open");

	fd = fork_proc_backend("table", table->t_config, table->t_name);
	if (fd == -1)
		fatalx("table-proc: exiting");

	imsg_init(&priv->ibuf, fd);

	memset(&op, 0, sizeof op);
	op.version = PROC_TABLE_API_VERSION;
	(void)strlcpy(op.name, table->t_name, sizeof op.name);
	imsg_compose(&priv->ibuf, PROC_TABLE_OPEN, 0, 0, -1, &op, sizeof op);

	table_proc_call(priv);
	table_proc_end();

	return (priv);
}
コード例 #3
0
ファイル: client.c プロジェクト: ThomasAdam/tmux-ARCHIVED
void
client_send_identify(int flags)
{
	struct msg_identify_data	data;
	struct winsize			ws;
	char			       *term;
	int				fd;

	if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
		fatal("ioctl(TIOCGWINSZ)");
	data.flags = flags;

	if (getcwd(data.cwd, sizeof data.cwd) == NULL)
		*data.cwd = '\0';

	term = getenv("TERM");
	if (term == NULL ||
	    strlcpy(data.term, term, sizeof data.term) >= sizeof data.term)
		*data.term = '\0';

	if ((fd = dup(STDIN_FILENO)) == -1)
		fatal("dup failed");
	imsg_compose(&client_ibuf,
	    MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
}
コード例 #4
0
ファイル: queue_proc.c プロジェクト: nmandery/deb-opensmtpd
static int
queue_proc_envelope_walk(uint64_t *evpid, char *buf, size_t len)
{
	int	r;

	imsg_compose(&ibuf, PROC_QUEUE_ENVELOPE_WALK, 0, 0, -1, NULL, 0);

	queue_proc_call();
	queue_proc_read(&r, sizeof(r));

	if (r > 0) {
		queue_proc_read(evpid, sizeof(*evpid));
		if (rlen > len) {
			log_warnx("warn: queue-proc: buf too small");
			fatalx("queue-proc: exiting");
		}
		if (r != (int)rlen) {
			log_warnx("warn: queue-proc: len mismatch");
			fatalx("queue-proc: exiting");
		}
		queue_proc_read(buf, rlen);
	}
	queue_proc_end();

	return (r);
}
コード例 #5
0
ファイル: ntpd.c プロジェクト: tunneleffekt/openntpd-openbsd
int
dispatch_imsg(struct ntpd_conf *lconf)
{
	struct imsg		 imsg;
	int			 n;
	double			 d;

	if ((n = imsg_read(ibuf)) == -1)
		return (-1);

	if (n == 0) {	/* connection closed */
		log_warnx("dispatch_imsg in main: pipe closed");
		return (-1);
	}

	for (;;) {
		if ((n = imsg_get(ibuf, &imsg)) == -1)
			return (-1);

		if (n == 0)
			break;

		switch (imsg.hdr.type) {
		case IMSG_ADJTIME:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d))
				fatalx("invalid IMSG_ADJTIME received");
			memcpy(&d, imsg.data, sizeof(d));
			n = ntpd_adjtime(d);
			imsg_compose(ibuf, IMSG_ADJTIME, 0, 0, -1,
			     &n, sizeof(n));
			break;
		case IMSG_ADJFREQ:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d))
				fatalx("invalid IMSG_ADJFREQ received");
			memcpy(&d, imsg.data, sizeof(d));
			ntpd_adjfreq(d, 1);
			break;
		case IMSG_SETTIME:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d))
				fatalx("invalid IMSG_SETTIME received");
			if (!lconf->settime)
				break;
			log_init(lconf->debug);
			memcpy(&d, imsg.data, sizeof(d));
			ntpd_settime(d);
			/* daemonize now */
			if (!lconf->debug)
				if (daemon(1, 0))
					fatal("daemon");
			lconf->settime = 0;
			timeout = INFTIM;
			break;
		default:
			break;
		}
		imsg_free(&imsg);
	}
	return (0);
}
コード例 #6
0
ファイル: table_proc.c プロジェクト: nmandery/deb-opensmtpd
static void
table_proc_close(void *arg)
{
	struct table_proc_priv	*priv = arg;

	imsg_compose(&priv->ibuf, PROC_TABLE_CLOSE, 0, 0, -1, NULL, 0);
	imsg_flush(&priv->ibuf);
}
コード例 #7
0
ファイル: queue_proc.c プロジェクト: appleorange1/bitrig
static int
queue_proc_init(struct passwd *pw, int server)
{
	int		sp[2];
	uint32_t	version;

	errno = 0;

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
		log_warn("warn: queue-proc: socketpair");
		return (0);
	}

	if ((pid = fork()) == -1) {
		log_warn("warn: queue-proc: fork");
		goto err;
	}

	if (pid == 0) {
		/* child process */
		dup2(sp[0], STDIN_FILENO);
		if (closefrom(STDERR_FILENO + 1) < 0)
			exit(1);

		execl(execpath, "queue_ramproc", NULL);
		err(1, "execl");
	}

	/* parent process */
	close(sp[0]);
	imsg_init(&ibuf, sp[1]);

	version = PROC_QUEUE_API_VERSION;
	imsg_compose(&ibuf, PROC_QUEUE_INIT, 0, 0, -1,
	    &version, sizeof(version));

	queue_api_on_message_create(queue_proc_message_create);
	queue_api_on_message_commit(queue_proc_message_commit);
	queue_api_on_message_delete(queue_proc_message_delete);
	queue_api_on_message_fd_r(queue_proc_message_fd_r);
	queue_api_on_message_corrupt(queue_proc_message_corrupt);
	queue_api_on_envelope_create(queue_proc_envelope_create);
	queue_api_on_envelope_delete(queue_proc_envelope_delete);
	queue_api_on_envelope_update(queue_proc_envelope_update);
	queue_api_on_envelope_load(queue_proc_envelope_load);
	queue_api_on_envelope_walk(queue_proc_envelope_walk);

	queue_proc_call();
	queue_proc_end();

	return (1);

err:
	close(sp[0]);
	close(sp[1]);
	return (0);
}
コード例 #8
0
ファイル: service_exec.c プロジェクト: i80and/network
static void dispatch(struct imsgbuf* ibuf, enum exec_type program, char* msg) {
    int32_t status = EXEC_RESPONSE_OK;
    char iface[IF_NAMESIZE] = {0};
    static char* buf = NULL;
    if(buf == NULL) { buf = malloc(EXEC_BUF_LEN); }
    if(buf == NULL) { die("Failed to allocate buffer"); }
    buf[0] = '\0';

    // Check if we were provided an interface on which to operate
    bool have_iface = (msg != NULL) &&
                      (msg = (char*)flatjson_next(msg, iface, sizeof(iface), NULL)) != NULL &&
                      validate_iface(iface);

    switch(program) {
        case EXEC_IFCONFIG_LIST_INTERFACES: {
            char* const args[] = {"/sbin/ifconfig", NULL};
            if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; }
            break;
        }
        case EXEC_IFCONFIG_LIST_PSEUDO_INTERFACES: {
            char* const args[] = {"/sbin/ifconfig", "-C", NULL};
            if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; }
            break;
        }
        case EXEC_IFCONFIG_DOWN: {
            if(!have_iface) {
                status = EXEC_RESPONSE_ERROR;
                break;
            }

            char* const args[] = {"/sbin/ifconfig", iface, "down", NULL};
            if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; }
            break;
        }
        case EXEC_NETSTART: {
            if(!have_iface) {
                status = EXEC_RESPONSE_ERROR;
                break;
            }

            char* const args[] = {"/bin/sh", "/etc/netstart", iface, NULL};
            if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; }
            break;
        }
        case EXEC_LOGEVENT: {
            char* const args[] = {"/usr/libexec/loghwevent", msg, NULL};
            if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; }
            break;
        }
        default:
            warn("Unknown exec mode");
            break;
    }

    imsg_compose(ibuf, status, 0, 0, -1, buf, strlen(buf) + 1);
    imsg_flush(ibuf);
}
コード例 #9
0
ファイル: server-fn.c プロジェクト: ThomasAdam/tmux-ARCHIVED
void
server_write_client(
    struct client *c, enum msgtype type, const void *buf, size_t len)
{
	struct imsgbuf	*ibuf = &c->ibuf;

	if (c->flags & CLIENT_BAD)
		return;
	log_debug("writing %d to client %d", type, c->ibuf.fd);
	imsg_compose(ibuf, type, PROTOCOL_VERSION, -1, -1, (void *) buf, len);
}
コード例 #10
0
ファイル: table_proc.c プロジェクト: edeln/OpenSMTPD
static void *
table_proc_open(struct table *table)
{
	int			 sp[2];
	struct table_proc_priv	*priv;
	char			*environ_new[2];
	struct table_open_params op;

	errno = 0;

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
		log_warn("warn: table-proc: socketpair");
		return (NULL);
	}
	priv = xcalloc(1, sizeof(*priv), "table_proc_open");

	if ((priv->pid = fork()) == -1) {
		log_warn("warn: table-proc: fork");
		goto err;
	}

	if (priv->pid == 0) {
		/* child process */
		dup2(sp[0], STDIN_FILENO);
		if (closefrom(STDERR_FILENO + 1) < 0)
			exit(1);

		environ_new[0] = "PATH=" _PATH_DEFPATH;
		environ_new[1] = (char *)NULL;
		environ = environ_new;
		execle("/bin/sh", "/bin/sh", "-c", table->t_config, (char *)NULL,
		    environ_new);
		fatal("execl");
	}

	/* parent process */
	close(sp[0]);
	imsg_init(&priv->ibuf, sp[1]);

	memset(&op, 0, sizeof op);
	op.version = PROC_TABLE_API_VERSION;
	(void)strlcpy(op.name, table->t_name, sizeof op.name);
	imsg_compose(&priv->ibuf, PROC_TABLE_OPEN, 0, 0, -1, &op, sizeof op);

	table_proc_call(priv);
	table_proc_end();

	return (priv);
err:
	free(priv);
	close(sp[0]);
	close(sp[1]);
	return (NULL);
}
コード例 #11
0
ファイル: queue_proc.c プロジェクト: nmandery/deb-opensmtpd
static int
queue_proc_message_fd_r(uint32_t msgid)
{
	imsg_compose(&ibuf, PROC_QUEUE_MESSAGE_FD_R, 0, 0, -1, &msgid,
	    sizeof(msgid));

	queue_proc_call();
	queue_proc_end();

	return (imsg.fd);
}
コード例 #12
0
ファイル: control.c プロジェクト: SylvestreG/bitrig
void
control_imsg_forward(struct imsg *imsg)
{
	struct ctl_conn *c;

	TAILQ_FOREACH(c, &ctl_conns, entry)
		if (c->flags & CTL_CONN_NOTIFY)
			imsg_compose(&c->iev.ibuf, imsg->hdr.type,
			    0, imsg->hdr.pid, -1, imsg->data,
			    imsg->hdr.len - IMSG_HEADER_SIZE);
}
コード例 #13
0
ファイル: imsgev.c プロジェクト: pandyxu/ldapd-portable
int
imsgev_compose(struct imsgev *iev, u_int16_t type, u_int32_t peerid,
    uint32_t pid, int fd, void *data, u_int16_t datalen)
{
	int	r;

	r = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, datalen);
	if (r != -1)
		imsgev_add(iev);

	return (r);
}
コード例 #14
0
ファイル: proc.c プロジェクト: appleorange1/bitrig
int
imsg_compose_event(struct imsgev *iev, u_int16_t type, u_int32_t peerid,
    pid_t pid, int fd, void *data, u_int16_t datalen)
{
	int	ret;

	if ((ret = imsg_compose(&iev->ibuf, type, peerid,
	    pid, fd, data, datalen)) == -1)
		return (ret);
	imsg_event_add(iev);
	return (ret);
}
コード例 #15
0
ファイル: queue_proc.c プロジェクト: nmandery/deb-opensmtpd
static int
queue_proc_close(void)
{
	int	r;

	imsg_compose(&ibuf, PROC_QUEUE_MESSAGE_CORRUPT, 0, 0, -1, NULL, 0);

	queue_proc_call();
	queue_proc_read(&r, sizeof(r));
	queue_proc_end();

	return (r);
}
コード例 #16
0
ファイル: table_proc.c プロジェクト: nmandery/deb-opensmtpd
static int
table_proc_update(struct table *table)
{
	struct table_proc_priv	*priv = table->t_handle;
	int r;

	imsg_compose(&priv->ibuf, PROC_TABLE_UPDATE, 0, 0, -1, NULL, 0);

	table_proc_call(priv);
	table_proc_read(&r, sizeof(r));
	table_proc_end();

	return (r);
}
コード例 #17
0
ファイル: queue_proc.c プロジェクト: nmandery/deb-opensmtpd
static int
queue_proc_message_corrupt(uint32_t msgid)
{
	int	r;

	imsg_compose(&ibuf, PROC_QUEUE_MESSAGE_CORRUPT, 0, 0, -1, &msgid,
	    sizeof(msgid));

	queue_proc_call();
	queue_proc_read(&r, sizeof(r));
	queue_proc_end();

	return (r);
}
コード例 #18
0
ファイル: queue_proc.c プロジェクト: nmandery/deb-opensmtpd
static int
queue_proc_envelope_delete(uint64_t evpid)
{
	int	r;

	imsg_compose(&ibuf, PROC_QUEUE_ENVELOPE_DELETE, 0, 0, -1, &evpid,
	    sizeof(evpid));

	queue_proc_call();
	queue_proc_read(&r, sizeof(r));
	queue_proc_end();

	return (r);
}
コード例 #19
0
ファイル: scheduler_proc.c プロジェクト: edeln/OpenSMTPD
static int
scheduler_proc_init(void)
{
	int		sp[2], r;
	uint32_t	version;

	errno = 0;

	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) {
		log_warn("warn: scheduler-proc: socketpair");
		goto err;
	}

	if ((pid = fork()) == -1) {
		log_warn("warn: scheduler-proc: fork");
		goto err;
	}

	if (pid == 0) {
		/* child process */
		dup2(sp[0], STDIN_FILENO);
		if (closefrom(STDERR_FILENO + 1) < 0)
			exit(1);

		execl(execpath, "scheduler-proc", NULL);
		err(1, "execl");
	}

	/* parent process */
	close(sp[0]);
	imsg_init(&ibuf, sp[1]);

	version = PROC_SCHEDULER_API_VERSION;
	imsg_compose(&ibuf, PROC_SCHEDULER_INIT, 0, 0, -1,
	    &version, sizeof(version));

	scheduler_proc_call();
	scheduler_proc_read(&r, sizeof(r));
	scheduler_proc_end();

	return (r);

err:
	close(sp[0]);
	close(sp[1]);
	fatalx("scheduler-proc: exiting");

	return (0);
}
コード例 #20
0
ファイル: scheduler_proc.c プロジェクト: edeln/OpenSMTPD
static int
scheduler_proc_insert(struct scheduler_info *si)
{
	int	r;

	log_debug("debug: scheduler-proc: PROC_SCHEDULER_INSERT");

	imsg_compose(&ibuf, PROC_SCHEDULER_INSERT, 0, 0, -1, si, sizeof(*si));

	scheduler_proc_call();
	scheduler_proc_read(&r, sizeof(r));
	scheduler_proc_end();

	return (r);
}
コード例 #21
0
ファイル: queue_proc.c プロジェクト: nmandery/deb-opensmtpd
static int
queue_proc_message_create(uint32_t *msgid)
{
	int	r;

	imsg_compose(&ibuf, PROC_QUEUE_MESSAGE_CREATE, 0, 0, -1, NULL, 0);

	queue_proc_call();
	queue_proc_read(&r, sizeof(r));
	if (r == 1)
		queue_proc_read(msgid, sizeof(*msgid));
	queue_proc_end();

	return (r);
}
コード例 #22
0
ファイル: mproc.c プロジェクト: OpenSMTPD/OpenSMTPD
void
m_close(struct mproc *p)
{
	if (imsg_compose(&p->imsgbuf, p->m_type, p->m_peerid, p->m_pid, p->m_fd,
	    p->m_buf, p->m_pos) == -1)
		fatal("imsg_compose");

	log_trace(TRACE_MPROC, "mproc: %s -> %s : %zu %s",
		    proc_name(smtpd_process),
		    proc_name(p->proc),
		    p->m_pos,
		    imsg_to_str(p->m_type));

	mproc_event_add(p);
}
コード例 #23
0
ファイル: mproc.c プロジェクト: OpenSMTPD/OpenSMTPD
void
m_compose(struct mproc *p, uint32_t type, uint32_t peerid, pid_t pid, int fd,
    void *data, size_t len)
{
	imsg_compose(&p->imsgbuf, type, peerid, pid, fd, data, len);

	if (type != IMSG_STAT_DECREMENT &&
	    type != IMSG_STAT_INCREMENT)
		log_trace(TRACE_MPROC, "mproc: %s -> %s : %zu %s",
		    proc_name(smtpd_process),
		    proc_name(p->proc),
		    len,
		    imsg_to_str(type));

	mproc_event_add(p);
}
コード例 #24
0
ファイル: scheduler_proc.c プロジェクト: edeln/OpenSMTPD
static int
scheduler_proc_delete(uint64_t evpid)
{
	int	r;

	log_debug("debug: scheduler-proc: PROC_SCHEDULER_DELETE");

	imsg_compose(&ibuf, PROC_SCHEDULER_DELETE, 0, 0, -1,
	    &evpid, sizeof(evpid));

	scheduler_proc_call();
	scheduler_proc_read(&r, sizeof(r));
	scheduler_proc_end();

	return (r);
}
コード例 #25
0
ファイル: scheduler_proc.c プロジェクト: edeln/OpenSMTPD
static size_t
scheduler_proc_rollback(uint32_t msgid)
{
	size_t	s;

	log_debug("debug: scheduler-proc: PROC_SCHEDULER_ROLLBACK");

	imsg_compose(&ibuf, PROC_SCHEDULER_ROLLBACK, 0, 0, -1,
	    &msgid, sizeof(msgid));

	scheduler_proc_call();
	scheduler_proc_read(&s, sizeof(s));
	scheduler_proc_end();

	return (s);
}
コード例 #26
0
ファイル: mproc.c プロジェクト: OpenSMTPD/OpenSMTPD
void
m_flush(struct mproc *p)
{
	if (imsg_compose(&p->imsgbuf, p->m_type, p->m_peerid, p->m_pid, p->m_fd,
	    p->m_buf, p->m_pos) == -1)
		fatal("imsg_compose");

	log_trace(TRACE_MPROC, "mproc: %s -> %s : %zu %s (flush)",
	    proc_name(smtpd_process),
	    proc_name(p->proc),
	    p->m_pos,
	    imsg_to_str(p->m_type));

	p->m_pos = 0;

	imsg_flush(&p->imsgbuf);
}
コード例 #27
0
ファイル: mproc.c プロジェクト: OpenSMTPD/OpenSMTPD
void
m_forward(struct mproc *p, struct imsg *imsg)
{
	imsg_compose(&p->imsgbuf, imsg->hdr.type, imsg->hdr.peerid,
	    imsg->hdr.pid, imsg->fd, imsg->data,
	    imsg->hdr.len - sizeof(imsg->hdr));

	if (imsg->hdr.type != IMSG_STAT_DECREMENT &&
	    imsg->hdr.type != IMSG_STAT_INCREMENT)
		log_trace(TRACE_MPROC, "mproc: %s -> %s : %zu %s (forward)",
		    proc_name(smtpd_process),
		    proc_name(p->proc),
		    imsg->hdr.len - sizeof(imsg->hdr),
		    imsg_to_str(imsg->hdr.type));

	mproc_event_add(p);
}
コード例 #28
0
ファイル: scheduler_proc.c プロジェクト: edeln/OpenSMTPD
static int
scheduler_proc_update(struct scheduler_info *si)
{
	int	r;

	log_debug("debug: scheduler-proc: PROC_SCHEDULER_UPDATE");

	imsg_compose(&ibuf, PROC_SCHEDULER_UPDATE, 0, 0, -1, si, sizeof(*si));

	scheduler_proc_call();
	scheduler_proc_read(&r, sizeof(r));
	if (r == 1)
		scheduler_proc_read(si, sizeof(*si));
	scheduler_proc_end();

	return (r);
}
コード例 #29
0
ファイル: proc.c プロジェクト: abergmann/tmate-slave
int
proc_send(struct tmuxpeer *peer, enum msgtype type, int fd, const void *buf,
    size_t len)
{
	struct imsgbuf	*ibuf = &peer->ibuf;
	void		*vp = (void *)buf;
	int		 retval;

	if (peer->flags & PEER_BAD)
		return (-1);
	log_debug("sending message %d to peer %p (%zu bytes)", type, peer, len);

	retval = imsg_compose(ibuf, type, PROTOCOL_VERSION, -1, fd, vp, len);
	if (retval != 1)
		return (-1);
	proc_update_event(peer);
	return (0);
}
コード例 #30
0
ファイル: tnetacle.c プロジェクト: LaKabane/tNETacle
/*
 * The purpose of this function is to handle requests sent by the
 * root privileged process.
 */
int
tnt_dispatch_imsg(struct imsg_data *data) {
    struct imsg imsg;
    ssize_t n;
    int device_fd;
    struct imsgbuf *ibuf = data->ibuf;

    n = imsg_read(ibuf);
    if (n == -1) {
        log_warnx("loose some imsgs");
        imsg_clear(ibuf);
        return -1;
    }

    if (n == 0) {
        log_warnx("pipe closed");
        return -1;
    }

    /* Loops through the queue created by imsg_read */
    while ((n = imsg_get(ibuf, &imsg)) != 0 && n != -1) {
        switch (imsg.hdr.type) {
            case IMSG_CREATE_DEV:
                device_fd = imsg.fd;
                log_info("receive IMSG_CREATE_DEV: fd %i", device_fd);

                server_set_device(data->server, device_fd);

                /* directly ask to configure the tun device */
                imsg_compose(ibuf, IMSG_SET_IP, 0, 0, -1,
                             serv_opts.addr , strlen(serv_opts.addr));
                break;
            default:
                break;
        }
        imsg_free(&imsg);
    }
    if (n == -1) {
        log_warnx("imsg_get");
        return -1;
    }
    return 0;
}