Example #1
0
int
queue_envelope_load(uint64_t evpid, struct envelope *ep)
{
	const char	*e;
	char		 evpbuf[sizeof(struct envelope)];
	size_t		 evplen;
	struct envelope	*cached;

	if ((env->sc_queue_flags & QUEUE_EVPCACHE) &&
	    (cached = tree_get(&evpcache_tree, evpid))) {
		*ep = *cached;
		stat_increment("queue.evpcache.load.hit", 1);
		return (1);
	}

	ep->id = evpid;
	profile_enter("queue_envelope_load");
	evplen = handler_envelope_load(ep->id, evpbuf, sizeof evpbuf);
	profile_leave();

	log_trace(TRACE_QUEUE,
	    "queue-backend: queue_envelope_load(%016"PRIx64") -> %zu",
	    evpid, evplen);

	if (evplen == 0)
		return (0);

	if (queue_envelope_load_buffer(ep, evpbuf, evplen)) {
		if ((e = envelope_validate(ep)) == NULL) {
			ep->id = evpid;
			if (env->sc_queue_flags & QUEUE_EVPCACHE) {
				queue_envelope_cache_add(ep);
				stat_increment("queue.evpcache.load.missed", 1);
			}
			return (1);
		}
		log_debug("debug: invalid envelope %016" PRIx64 ": %s",
		    ep->id, e);
	}

	(void)queue_message_corrupt(evpid_to_msgid(evpid));
	return (0);
}
Example #2
0
static void
queue_msg_dispatch(void)
{
	uint64_t	 evpid;
	uint32_t	 msgid, version;
	size_t		 n;
	char		 buffer[8192], path[SMTPD_MAXPATHLEN];
	int		 r, fd;
	FILE		*ifile, *ofile;

	switch (imsg.hdr.type) {
	case PROC_QUEUE_INIT:
		queue_msg_get(&version, sizeof(version));
		queue_msg_end();

		if (version != PROC_QUEUE_API_VERSION) {
			log_warnx("warn: queue-api: bad API version");
			fatalx("queue-api: exiting");
		}

		imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, -1, NULL, 0);
		break;

	case PROC_QUEUE_MESSAGE_CREATE:
		queue_msg_end();

		r = handler_message_create(&msgid);

		queue_msg_add(&r, sizeof(r));
		if (r == 1)
			queue_msg_add(&msgid, sizeof(msgid));
		queue_msg_close();
		break;

	case PROC_QUEUE_MESSAGE_DELETE:
		queue_msg_get(&msgid, sizeof(msgid));
		queue_msg_end();

		r = handler_message_delete(msgid);

		imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, -1, &r, sizeof(r));
		break;

	case PROC_QUEUE_MESSAGE_COMMIT:
		queue_msg_get(&msgid, sizeof(msgid));
		queue_msg_end();

		/* XXX needs more love */
		r = -1;
		fd = mkstemp(path);
		if (fd == -1) {
			log_warn("warn: queue-api: mkstemp");
		}
		else {
			ifile = fdopen(imsg.fd, "r");
			ofile = fdopen(fd, "w");
			if (ifile && ofile) {
				while (!feof(ifile)) {
					n = fread(buffer, 1, sizeof(buffer),
					    ifile);
					fwrite(buffer, 1, n, ofile);
				}
				r = handler_message_commit(msgid, path);
			}
			if (ifile)
				fclose(ifile);
			if (ofile)
				fclose(ofile);
		}

		imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, -1, &r, sizeof(r));
		break;

	case PROC_QUEUE_MESSAGE_FD_R:
		queue_msg_get(&msgid, sizeof(msgid));
		queue_msg_end();

		fd = handler_message_fd_r(msgid);

		imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, fd, NULL, 0);
		break;

	case PROC_QUEUE_MESSAGE_CORRUPT:
		queue_msg_get(&msgid, sizeof(msgid));
		queue_msg_end();

		r = handler_message_corrupt(msgid);

		imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, -1, &r, sizeof(r));
		break;

	case PROC_QUEUE_ENVELOPE_CREATE:
		queue_msg_get(&msgid, sizeof(msgid));
		r = handler_envelope_create(msgid, rdata, rlen, &evpid);
		queue_msg_get(NULL, rlen);
		queue_msg_end();

		queue_msg_add(&r, sizeof(r));
		if (r == 1)
			queue_msg_add(&evpid, sizeof(evpid));
		queue_msg_close();
		break;

	case PROC_QUEUE_ENVELOPE_DELETE:
		queue_msg_get(&evpid, sizeof(evpid));
		queue_msg_end();

		r = handler_envelope_delete(evpid);

		imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, -1, &r, sizeof(r));
		break;

	case PROC_QUEUE_ENVELOPE_LOAD:
		queue_msg_get(&evpid, sizeof(evpid));
		queue_msg_end();

		r = handler_envelope_load(evpid, buffer, sizeof(buffer));

		imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, -1, buffer, r);
		break;

	case PROC_QUEUE_ENVELOPE_UPDATE:
		queue_msg_get(&evpid, sizeof(evpid));
		r = handler_envelope_update(evpid, rdata, rlen);
		queue_msg_get(NULL, rlen);
		queue_msg_end();

		imsg_compose(&ibuf, PROC_QUEUE_OK, 0, 0, -1, &r, sizeof(r));
		break;

	case PROC_QUEUE_ENVELOPE_WALK:
		queue_msg_end();

		r = handler_envelope_walk(&evpid, buffer, sizeof(buffer));

		queue_msg_add(&r, sizeof(r));
		if (r > 0) {
			queue_msg_add(&evpid, sizeof(evpid));
			queue_msg_add(buffer, r);
		}
		queue_msg_close();

	default:
		log_warnx("warn: queue-api: bad message %i", imsg.hdr.type);
		fatalx("queue-api: exiting");
	}
}