Beispiel #1
0
void
strb_vadd(struct strb **sbp, const char *key, const char *value, va_list ap)
{
	struct strb	*sb = *sbp;
	size_t		 size, keylen, valuelen;
	u_int		 n;
	struct strbent	 sbe, *sbep;
	va_list		 aq;

	keylen = strlen(key) + 1;

	va_copy(aq, ap);
	valuelen = xvsnprintf(NULL, 0, value, aq) + 1;
	va_end(aq);

	size = sb->str_size;
	while (sb->str_size - sb->str_used < keylen + valuelen) {
		if (STRB_SIZE(sb) > SIZE_MAX / 2)
			fatalx("size too large");
		sb->str_size *= 2;
	}
	if (size != sb->str_size) {
		sb = *sbp = xrealloc(sb, 1, STRB_SIZE(sb));
		memmove(
		    STRB_ENTBASE(sb), STRB_BASE(sb) + size, STRB_ENTSIZE(sb));
		memset(STRB_BASE(sb) + size, 0, sb->str_size - size);
	}

	sbep = strb_address(sb, key);
	if (sbep == NULL) {
		if (sb->ent_used > sb->ent_max) {
			/* Allocate some more entries. */
			n = sb->ent_max;

			size = STRB_SIZE(sb);
			if (sb->ent_max > UINT_MAX / 2)
				fatalx("ent_max too large");
			sb->ent_max *= 2;
			if (STRB_SIZE(sb) < size)
				fatalx("size too large");

			sb = *sbp = xrealloc(sb, 1, STRB_SIZE(sb));

			memset(STRB_ENTRY(sb, n), 0, STRB_ENTSIZE(sb) / 2);
		}

		sbep = STRB_ENTRY(sb, sb->ent_used);
		sb->ent_used++;

		sbe.key = sb->str_used;
		memcpy(STRB_KEY(sb, &sbe), key, keylen);
		sb->str_used += keylen;
	} else
		memcpy(&sbe, sbep, sizeof sbe);
	sbe.value = sb->str_used;
	xvsnprintf(STRB_VALUE(sb, &sbe), valuelen, value, ap);
	sb->str_used += valuelen;

	memcpy(sbep, &sbe, sizeof sbe);
}
Beispiel #2
0
int
match_command_match(struct mail_ctx *mctx, struct expritem *ei)
{
	struct match_command_data	*data = ei->data;
	struct account			*a = mctx->account;
	struct mail			*m = mctx->mail;
	struct io			*io = mctx->io;
	struct msg			 msg;
	struct msgbuf			 msgbuf;
	struct userdata			*ud;
	char				*user;

	set_wrapped(m, '\n');

	/*
	 * We are called as the child so to change uid this needs to be done
	 * largely in the parent.
	 */
	memset(&msg, 0, sizeof msg);
	msg.type = MSG_COMMAND;
	msg.id = m->idx;

	msg.data.account = a;
	msg.data.cmddata = data;

	user = conf.cmd_user;
	if (data->user.str != NULL)
		user = replacestr(&data->user, m->tags, m, &m->rml);
	if ((ud = user_lookup(user, conf.user_order)) == NULL) {
		log_warnx("%s: bad user: %s", a->name, user);
		return (MATCH_ERROR);
	}
	if (data->user.str != NULL)
		xfree(user);

	msg.data.uid = ud->uid;
	msg.data.gid = ud->gid;
	update_tags(&m->tags, ud);
	user_free(ud);

	msgbuf.buf = m->tags;
	msgbuf.len = STRB_SIZE(m->tags);

	mail_send(m, &msg);

	if (privsep_send(io, &msg, &msgbuf) != 0)
		fatalx("privsep_send error");

	reset_tags(&m->tags);

	mctx->msgid = msg.id;
	return (MATCH_PARENT);
}
Beispiel #3
0
void
strb_clear(struct strb **sbp)
{
	struct strb	*sb = *sbp;

	sb->ent_used = 0;
	sb->ent_max = STRBENTRIES;

	sb->str_size = STRBBLOCK;
	sb->str_used = 0;

	sb = *sbp = xrealloc(sb, 1, STRB_SIZE(sb));
	memset(STRB_BASE(sb), 0, sb->str_size + STRB_ENTSIZE(sb));
}
Beispiel #4
0
int
child_deliver(struct child *child, struct io *pio)
{
	struct child_deliver_data	*data = child->data;
	struct account			*a = data->account;
	struct mail			*m = data->mail;
	struct msg			 msg;
	struct msgbuf			 msgbuf;
	int				 error = 0;

#ifdef DEBUG
	xmalloc_clear();
	COUNTFDS(a->name);
#endif

	log_debug2("%s: deliver started, pid %ld", a->name, (long) getpid());

#ifdef HAVE_SETPROCTITLE
	setproctitle("%s[%lu]", data->name, (u_long) geteuid());
#endif

	/* Call the hook. */
	memset(&msg, 0, sizeof msg);
	data->hook(0, a, &msg, data, &msg.data.error);

	/* Inform parent we're done. */
	msg.type = MSG_DONE;
	msg.id = 0;

	msgbuf.buf = m->tags;
	msgbuf.len = STRB_SIZE(m->tags);

	if (privsep_send(pio, &msg, &msgbuf) != 0)
		fatalx("privsep_send error");
	do {
		if (privsep_recv(pio, &msg, NULL) != 0)
			fatalx("privsep_recv error");
	} while (msg.type != MSG_EXIT);

#ifdef DEBUG
	COUNTFDS(a->name);
	xmalloc_report(getpid(), a->name);
#endif

	return (error);
}