mbox-expunge.c revision 007d354a674fb3ddf49db160cf050cf61270a1a0
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (C) 2002 Timo Sirainen */
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenbergerstatic int expunge_real(struct index_mailbox *ibox,
06ff2a72c39cb34cc6425f17fc82c5e93fef2018Timo Sirainen struct mail_index_record *rec, unsigned int seq,
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen struct istream *input, struct ostream *output,
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen uoff_t end_offset, from_offset, copy_size, old_limit;
3ddbbe03fe74b3ee7b1dff4e08ec706d7880d052Timo Sirainen const unsigned char *data;
c9dea5c23355dea35c6fa423de69f6507852efe4Timo Sirainen /* we need to find offset to beginning of From-line.
c9dea5c23355dea35c6fa423de69f6507852efe4Timo Sirainen not the fastest way maybe, but easiest.. */
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen rec = ibox->index->lookup(ibox->index, seq-1);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen if (!mbox_mail_get_location(ibox->index, rec, &offset,
2b3b0df76184799317584b596af8df5afec3ebddTimo Sirainen /* get back to the deleted record */
5ce2084ada06ade9f44fc2914c34658e9a842dc1Timo Sirainen if (!mbox_mail_get_location(ibox->index, rec, &offset,
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen if (!index_expunge_mail(ibox, rec, seq, notify))
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen /* first expunged record, seek to position
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen where we want to begin writing */
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen /* seek to wanted input position, and copy
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen this messages */
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen i_stream_skip(input, from_offset - input->v_offset);
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen /* we're writing to beginning of mbox, so we
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen don't want the [\r]\n there */
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen failed = o_stream_send_istream(output, input) < 0;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen i_stream_skip(input, end_offset - input->v_offset);
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen /* copy the rest as well, should be only \n but someone might
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen as well just appended more data.. but if we've deleted all mail,
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen don't write the only \n there. */
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen return o_stream_send_istream(output, input) >= 0;
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainenint mbox_expunge_locked(struct index_mailbox *ibox, int notify)
51cbc45fc1ac5dde29bc2adbb175945df1b4f7d4Timo Sirainen unsigned int seq;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (!index_expunge_seek_first(ibox, &seq, &rec))
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen /* no deleted messages */
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen /* mbox must be already opened, synced and locked at this point.
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen we just want the istream. */
e82e363e7a6917f470412d629db6c5b1f5891a35Timo Sirainen input = mbox_get_stream(ibox->index, 0, MAIL_LOCK_EXCLUSIVE);
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen output = o_stream_create_file(ibox->index->mbox_fd, data_stack_pool,
d6c5ceea8521b92d10e51a59da00c792f6140b1dTimo Sirainen o_stream_set_blocking(output, 60000, NULL, NULL);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen failed = !expunge_real(ibox, rec, seq, input, output, notify);
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen /* we moved some of the data. move the rest as well so there
d10a370b2614712d9cb6a1dd8625f62a071b6377Timo Sirainen won't be invalid holes in mbox file */
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen if (ftruncate(ibox->index->mbox_fd, (off_t)output->offset) < 0) {
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen mail_storage_set_error(ibox->box.storage, "ftruncate() failed "
88ea893b45d3ed8d68000921db9156c03cbe1b00Timo Sirainen "for mbox file %s: %m",