Ejemplo n.º 1
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");
	}
}
Ejemplo n.º 2
0
int
queue_message_fd_r(uint32_t msgid)
{
	int	fdin, fdout = -1, fd = -1;
	FILE	*ifp = NULL;
	FILE	*ofp = NULL;

	profile_enter("queue_message_fd_r");
	fdin = handler_message_fd_r(msgid);
	profile_leave();

	log_trace(TRACE_QUEUE,
	    "queue-backend: queue_message_fd_r(%08"PRIx32") -> %d", msgid, fdin);

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

	if (env->sc_queue_flags & QUEUE_ENCRYPTION) {
		if ((fdout = mktmpfile()) == -1)
			goto err;
		if ((fd = dup(fdout)) == -1)
			goto err;
		if ((ifp = fdopen(fdin, "r")) == NULL)
			goto err;
		fdin = fd;
		fd = -1;
		if ((ofp = fdopen(fdout, "w+")) == NULL)
			goto err;

		if (! crypto_decrypt_file(ifp, ofp))
			goto err;

		fclose(ifp);
		ifp = NULL;
		fclose(ofp);
		ofp = NULL;
		lseek(fdin, SEEK_SET, 0);
	}

	if (env->sc_queue_flags & QUEUE_COMPRESSION) {
		if ((fdout = mktmpfile()) == -1)
			goto err;
		if ((fd = dup(fdout)) == -1)
			goto err;
		if ((ifp = fdopen(fdin, "r")) == NULL)
			goto err;
		fdin = fd;
		fd = -1;
		if ((ofp = fdopen(fdout, "w+")) == NULL)
			goto err;

		if (! uncompress_file(ifp, ofp))
			goto err;

		fclose(ifp);
		ifp = NULL;
		fclose(ofp);
		ofp = NULL;
		lseek(fdin, SEEK_SET, 0);
	}

	return (fdin);

err:
	if (fd != -1)
		close(fd);
	if (fdin != -1)
		close(fdin);
	if (fdout != -1)
		close(fdout);
	if (ifp)
		fclose(ifp);
	if (ofp)
		fclose(ofp);
	return -1;
}