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); }
int queue_message_delete(uint32_t msgid) { char msgpath[PATH_MAX]; uint64_t evpid; void *iter; int r; profile_enter("queue_message_delete"); r = handler_message_delete(msgid); profile_leave(); /* in case the message is incoming */ queue_message_path(msgid, msgpath, sizeof(msgpath)); unlink(msgpath); /* remove remaining envelopes from the cache if any (on rollback) */ evpid = msgid_to_evpid(msgid); for (;;) { iter = NULL; if (!tree_iterfrom(&evpcache_tree, &iter, evpid, &evpid, NULL)) break; if (evpid_to_msgid(evpid) != msgid) break; queue_envelope_cache_del(evpid); } log_trace(TRACE_QUEUE, "queue-backend: queue_message_delete(%08"PRIx32") -> %d", msgid, r); return (r); }
int queue_envelope_create(struct envelope *ep) { int r; char evpbuf[sizeof(struct envelope)]; size_t evplen; uint64_t evpid; uint32_t msgid; ep->creation = time(NULL); evplen = queue_envelope_dump_buffer(ep, evpbuf, sizeof evpbuf); if (evplen == 0) return (0); evpid = ep->id; msgid = evpid_to_msgid(evpid); profile_enter("queue_envelope_create"); r = handler_envelope_create(msgid, evpbuf, evplen, &ep->id); profile_leave(); log_trace(TRACE_QUEUE, "queue-backend: queue_envelope_create(%016"PRIx64", %zu) -> %d (%016"PRIx64")", evpid, evplen, r, ep->id); if (!r) { ep->creation = 0; ep->id = 0; } if (r && env->sc_queue_flags & QUEUE_EVPCACHE) queue_envelope_cache_add(ep); return (r); }
int queue_message_corrupt(uint32_t msgid) { int r; profile_enter("queue_message_corrupt"); r = handler_message_corrupt(msgid); profile_leave(); log_trace(TRACE_QUEUE, "queue-backend: queue_message_corrupt(%08"PRIx32") -> %d", msgid, r); return (r); }
int queue_message_create(uint32_t *msgid) { int r; profile_enter("queue_message_create"); r = handler_message_create(msgid); profile_leave(); log_trace(TRACE_QUEUE, "queue-backend: queue_message_create() -> %d (%08"PRIx32")", r, *msgid); return (r); }
int queue_envelope_delete(uint64_t evpid) { int r; if (env->sc_queue_flags & QUEUE_EVPCACHE) queue_envelope_cache_del(evpid); profile_enter("queue_envelope_delete"); r = handler_envelope_delete(evpid); profile_leave(); log_trace(TRACE_QUEUE, "queue-backend: queue_envelope_delete(%016"PRIx64") -> %d", evpid, r); return (r); }
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); }
int queue_message_delete(uint32_t msgid) { char msgpath[PATH_MAX]; int r; profile_enter("queue_message_delete"); r = handler_message_delete(msgid); profile_leave(); /* in case the message is incoming */ queue_message_path(msgid, msgpath, sizeof(msgpath)); unlink(msgpath); log_trace(TRACE_QUEUE, "queue-backend: queue_message_delete(%08"PRIx32") -> %d", msgid, r); return (r); }
int queue_message_walk(struct envelope *ep, uint32_t msgid, int *done, void **data) { char evpbuf[sizeof(struct envelope)]; uint64_t evpid; int r; const char *e; profile_enter("queue_message_walk"); r = handler_message_walk(&evpid, evpbuf, sizeof evpbuf, msgid, done, data); profile_leave(); log_trace(TRACE_QUEUE, "queue-backend: queue_message_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; /* * do not cache the envelope here, while discovering * envelopes one could re-run discover on already * scheduled envelopes which leads to triggering of * strict checks in caching. Envelopes could anyway * be loaded from backend if it isn't cached. */ return (1); } log_debug("debug: invalid envelope %016" PRIx64 ": %s", ep->id, e); (void)queue_message_corrupt(evpid_to_msgid(evpid)); } return (0); }
int queue_envelope_update(struct envelope *ep) { char evpbuf[sizeof(struct envelope)]; size_t evplen; int r; evplen = queue_envelope_dump_buffer(ep, evpbuf, sizeof evpbuf); if (evplen == 0) return (0); profile_enter("queue_envelope_update"); r = handler_envelope_update(ep->id, evpbuf, evplen); profile_leave(); if (r && env->sc_queue_flags & QUEUE_EVPCACHE) queue_envelope_cache_update(ep); log_trace(TRACE_QUEUE, "queue-backend: queue_envelope_update(%016"PRIx64") -> %d", ep->id, r); return (r); }
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; }
int queue_message_commit(uint32_t msgid) { int r; char msgpath[PATH_MAX]; char tmppath[PATH_MAX]; FILE *ifp = NULL; FILE *ofp = NULL; profile_enter("queue_message_commit"); queue_message_path(msgid, msgpath, sizeof(msgpath)); if (env->sc_queue_flags & QUEUE_COMPRESSION) { bsnprintf(tmppath, sizeof tmppath, "%s.comp", msgpath); ifp = fopen(msgpath, "r"); ofp = fopen(tmppath, "w+"); if (ifp == NULL || ofp == NULL) goto err; if (! compress_file(ifp, ofp)) goto err; fclose(ifp); fclose(ofp); ifp = NULL; ofp = NULL; if (rename(tmppath, msgpath) == -1) { if (errno == ENOSPC) return (0); unlink(tmppath); log_warn("rename"); return (0); } } if (env->sc_queue_flags & QUEUE_ENCRYPTION) { bsnprintf(tmppath, sizeof tmppath, "%s.enc", msgpath); ifp = fopen(msgpath, "r"); ofp = fopen(tmppath, "w+"); if (ifp == NULL || ofp == NULL) goto err; if (! crypto_encrypt_file(ifp, ofp)) goto err; fclose(ifp); fclose(ofp); ifp = NULL; ofp = NULL; if (rename(tmppath, msgpath) == -1) { if (errno == ENOSPC) return (0); unlink(tmppath); log_warn("rename"); return (0); } } r = handler_message_commit(msgid, msgpath); profile_leave(); /* in case it's not done by the backend */ unlink(msgpath); log_trace(TRACE_QUEUE, "queue-backend: queue_message_commit(%08"PRIx32") -> %d", msgid, r); return (r); err: if (ifp) fclose(ifp); if (ofp) fclose(ofp); return 0; }