mailbox-log.c revision 5e9713e7b02b2b47c339476725f9fbfd9bf78cff
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenstatic void mailbox_log_close(struct mailbox_log *log);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenstruct mailbox_log *mailbox_log_alloc(const char *path)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen log->filepath2 = i_strconcat(path, ".2", NULL);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainenvoid mailbox_log_free(struct mailbox_log **_log)
35fcdde46a71ac151c2518d48c841019f1181bb2Timo Sirainenstatic void mailbox_log_close(struct mailbox_log *log)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen i_error("close(%s) failed: %m", log->filepath);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenvoid mailbox_log_set_permissions(struct mailbox_log *log, mode_t mode,
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainenstatic int mailbox_log_open(struct mailbox_log *log)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen log->fd = open(log->filepath, O_RDWR | O_APPEND);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen /* try to create it */
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen log->fd = open(log->filepath, O_RDWR | O_APPEND | O_CREAT, 0666);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen i_error("creat(%s) failed: %m", log->filepath);
93a7d1ee4b518b5c85f9721dc6539e4dab6aae00Timo Sirainen i_error("%s", eacces_error_get("creat", log->filepath));
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (fchown(log->fd, (uid_t)-1, log->gid) < 0) {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen i_error("fchown(%s) failed: %m", log->filepath);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic int mailbox_log_rotate_if_needed(struct mailbox_log *log)
559f278a4c54d9fa7e0f2e96ebceda30562f9009Timo Sirainen i_error("fstat(%s) failed: %m", log->filepath);
380dbb60ae291cbe39d1f710284562ca9167150bTimo Sirainen if (rename(log->filepath, log->filepath2) < 0 && errno != ENOENT) {
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainenvoid mailbox_log_record_set_timestamp(struct mailbox_log_record *rec,
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen rec->timestamp[0] = (stamp & 0xff000000) >> 24;
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen rec->timestamp[1] = (stamp & 0x00ff0000) >> 16;
559f278a4c54d9fa7e0f2e96ebceda30562f9009Timo Sirainen rec->timestamp[2] = (stamp & 0x0000ff00) >> 8;
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainentime_t mailbox_log_record_get_timestamp(const struct mailbox_log_record *rec)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainenint mailbox_log_append(struct mailbox_log *log,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen /* we don't have to be too strict about appending to the latest log
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen file. the records' ordering doesn't matter and iteration goes
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen through both logs anyway. */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* We don't bother with locking, atomic appends will protect us.
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen If they don't (NFS), the worst that can happen is that a few
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen records get overwritten (because they're all the same size).
544a727de8ab0e6c55cab18a7ee475fffdf5eff3Timo Sirainen This whole log isn't supposed to be super-reliable anyway. */
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen i_error("write(%s) failed: %m", log->filepath);
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen i_error("write(%s) wrote %d/%u bytes", log->filepath,
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen if (ftruncate(log->fd, st.st_size - ret) < 0) {
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainenstatic bool mailbox_log_iter_open_next(struct mailbox_log_iter *iter)
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen i_error("close(%s) failed: %m", iter->filepath);
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen else if (iter->filepath == iter->log->filepath2)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen iter->fd = open(iter->filepath, O_RDONLY | O_APPEND);
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen i_error("open(%s) failed: %m", iter->filepath);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstruct mailbox_log_iter *mailbox_log_iter_init(struct mailbox_log *log)
61618d4c58080570f689614fec204ae14e90cef2Timo Sirainenmailbox_log_iter_next(struct mailbox_log_iter *iter)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ret = pread(iter->fd, iter->buf, sizeof(iter->buf),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen i_error("pread(%s) failed: %m", iter->filepath);
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi if (ret == 0) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen iter->offset += iter->count * sizeof(iter->buf[0]);
4addfd26372c6ae32ec93252696d86fd32081327Timo Sirainen if (rec->type < MAILBOX_LOG_RECORD_DELETE_MAILBOX ||
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen (iter->count - iter->idx) * sizeof(iter->buf[0]);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen i_error("Corrupted mailbox log at offset %"PRIuUOFF_T": %s",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen i_error("unlink(%s) failed: %m", iter->filepath);
f01eb1f51d618633c0189be9ab60a774f47fb7dfTimo Sirainenint mailbox_log_iter_deinit(struct mailbox_log_iter **_iter)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen i_error("close(%s) failed: %m", iter->filepath);