Пример #1
0
int
queue_envelope_walk(struct envelope *ep)
{
	const char	*e;
	uint64_t	 evpid;
	char		 evpbuf[sizeof(struct envelope)];
	int		 r;

	profile_enter("queue_envelope_walk");
	r = handler_envelope_walk(&evpid, evpbuf, sizeof evpbuf);
	profile_leave();

	log_trace(TRACE_QUEUE,
	    "queue-backend: queue_envelope_walk() -> %d (%016"PRIx64")",
	    r, evpid);

	if (r == -1)
		return (r);

	if (r && queue_envelope_load_buffer(ep, evpbuf, (size_t)r)) {
		if ((e = envelope_validate(ep)) == NULL) {
			ep->id = evpid;
			if (env->sc_queue_flags & QUEUE_EVPCACHE)
				queue_envelope_cache_add(ep);
			return (1);
		}
		log_debug("debug: invalid envelope %016" PRIx64 ": %s",
		    ep->id, e);
		(void)queue_message_corrupt(evpid_to_msgid(evpid));
	}

	return (0);
}
Пример #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");
	}
}