subscription-file.c revision 728a9c39b63b48f17600e6a1e5ebfc93d0896a24
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "lib.h"
49e358eebea107aad9919dcc4bd88cee8519ba2eTimo Sirainen#include "istream.h"
49e358eebea107aad9919dcc4bd88cee8519ba2eTimo Sirainen#include "ostream.h"
49e358eebea107aad9919dcc4bd88cee8519ba2eTimo Sirainen#include "nfs-workarounds.h"
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen#include "file-dotlock.h"
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen#include "mailbox-list-private.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "subscription-file.h"
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen#include <unistd.h>
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen#include <fcntl.h>
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen#define SUBSCRIPTION_FILE_ESTALE_RETRY_COUNT NFS_ESTALE_RETRY_COUNT
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen#define SUBSCRIPTION_FILE_LOCK_TIMEOUT 120
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen#define SUBSCRIPTION_FILE_CHANGE_TIMEOUT 30
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainenstruct subsfile_list_context {
7b29ccd796fc75af86f827192d2f8c0e8f0087bbTimo Sirainen pool_t pool;
7b29ccd796fc75af86f827192d2f8c0e8f0087bbTimo Sirainen
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen struct mailbox_list *list;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct istream *input;
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen const char *path;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool failed;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen};
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
da2aa032ccfa8e7e4a4380ef738014549f4d2c2dTimo Sirainenstatic void subsfile_set_syscall_error(struct mailbox_list *list,
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen const char *function, const char *path)
7b29ccd796fc75af86f827192d2f8c0e8f0087bbTimo Sirainen{
7b29ccd796fc75af86f827192d2f8c0e8f0087bbTimo Sirainen i_assert(function != NULL);
7b29ccd796fc75af86f827192d2f8c0e8f0087bbTimo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (errno == EACCES)
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen mailbox_list_set_error(list, "Permission denied");
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen else {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen mailbox_list_set_critical(list,
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen "%s failed with subscription file %s: %m",
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen function, path);
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi }
43834f87bf431198f986e86052a4f6e558fdb07dTimo Sirainen}
43834f87bf431198f986e86052a4f6e558fdb07dTimo Sirainen
09801f106cd531a28b4e03ec665e44c421264560Timo Sirainenstatic const char *next_line(struct mailbox_list *list, const char *path,
09801f106cd531a28b4e03ec665e44c421264560Timo Sirainen struct istream *input, bool *failed_r,
09801f106cd531a28b4e03ec665e44c421264560Timo Sirainen bool ignore_estale)
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen{
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen const char *line;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch *failed_r = FALSE;
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch if (input == NULL)
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen return NULL;
212a34c06ff45952c008ae9eec387ced783de6cfPhil Carmody
212a34c06ff45952c008ae9eec387ced783de6cfPhil Carmody while ((line = i_stream_next_line(input)) == NULL) {
212a34c06ff45952c008ae9eec387ced783de6cfPhil Carmody switch (i_stream_read(input)) {
212a34c06ff45952c008ae9eec387ced783de6cfPhil Carmody case -1:
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch if (input->stream_errno != 0 &&
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch (input->stream_errno != ESTALE || !ignore_estale)) {
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch subsfile_set_syscall_error(list,
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch "read()", path);
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch *failed_r = TRUE;
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch }
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch return NULL;
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch case -2:
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch /* mailbox name too large */
10c96a244935de4add8213ba0b894178dfb889a5Timo Sirainen mailbox_list_set_critical(list,
bdcb00145ad87765e3fd22d4ebc4d2c029a326b9Timo Sirainen "Subscription file %s contains lines longer "
bdcb00145ad87765e3fd22d4ebc4d2c029a326b9Timo Sirainen "than %u characters", path,
0c1835a90dd1dcedaeaedd1cd91672299cbeb5beTimo Sirainen (unsigned int)list->mailbox_name_max_length);
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Sirainen *failed_r = TRUE;
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Sirainen return NULL;
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Sirainen }
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen }
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen return line;
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen}
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainenint subsfile_set_subscribed(struct mailbox_list *list, const char *path,
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen const char *temp_prefix, const char *name, bool set)
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen{
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen struct dotlock_settings dotlock_set;
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen struct dotlock *dotlock;
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen const char *line;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct istream *input;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct ostream *output;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen int fd_in, fd_out;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen bool found, failed = FALSE;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainen if (strcasecmp(name, "INBOX") == 0)
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen name = "INBOX";
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen memset(&dotlock_set, 0, sizeof(dotlock_set));
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen dotlock_set.use_excl_lock =
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen (list->flags & MAILBOX_LIST_FLAG_DOTLOCK_USE_EXCL) != 0;
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen dotlock_set.temp_prefix = temp_prefix;
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen dotlock_set.timeout = SUBSCRIPTION_FILE_LOCK_TIMEOUT;
c28f6aa0b70af4811c9ace9114fe827c2f503455Timo Sirainen dotlock_set.stale_timeout = SUBSCRIPTION_FILE_CHANGE_TIMEOUT;
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen fd_out = file_dotlock_open(&dotlock_set, path, 0, &dotlock);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (fd_out == -1) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (errno == EAGAIN) {
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen mailbox_list_set_error(list,
46ce4d9273e6df12ef1912bbdb1c8b84b104f394Timo Sirainen "Timeout waiting for subscription file lock");
46ce4d9273e6df12ef1912bbdb1c8b84b104f394Timo Sirainen } else {
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen subsfile_set_syscall_error(list,
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen "file_dotlock_open()", path);
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen }
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen return -1;
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen }
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen fd_in = nfs_safe_open(path, O_RDONLY);
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen if (fd_in == -1 && errno != ENOENT) {
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen subsfile_set_syscall_error(list, "open()", path);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen (void)file_dotlock_delete(&dotlock);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen return -1;
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen }
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen input = fd_in == -1 ? NULL :
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen i_stream_create_file(fd_in, default_pool,
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen list->mailbox_name_max_length+1, TRUE);
7662010b03ffe5f2a6ecf4b4eb220d1c65efea76Timo Sirainen output = o_stream_create_file(fd_out, default_pool,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen list->mailbox_name_max_length+1, FALSE);
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen found = FALSE;
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen while ((line = next_line(list, path, input,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen &failed, FALSE)) != NULL) {
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen if (strcmp(line, name) == 0) {
19557f192d37cd54a1a090a8a26d9d47265e4413Aki Tuomi found = TRUE;
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen if (!set)
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen continue;
0a49b316fc729e5d57268ffa63c7122ac73f994cTimo Sirainen }
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen if (o_stream_send_str(output, line) < 0 ||
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen o_stream_send(output, "\n", 1) < 0) {
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen subsfile_set_syscall_error(list, "write()", path);
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen failed = TRUE;
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen break;
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen }
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen }
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen
0b6924ad1943fe5c6917fc49f675d8f316b0d939Timo Sirainen if (!failed && set && !found) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* append subscription */
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen line = t_strconcat(name, "\n", NULL);
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen if (o_stream_send_str(output, line) < 0) {
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen subsfile_set_syscall_error(list, "write()", path);
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen failed = TRUE;
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen }
e0fab14602b73ff590b2a9c5d9e67e2dfb5d1f9eTimo Sirainen }
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen if (!failed && fsync(fd_out) < 0) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen subsfile_set_syscall_error(list, "fsync()", path);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen failed = TRUE;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen }
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainen if (input != NULL)
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen i_stream_destroy(&input);
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen o_stream_destroy(&output);
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen if (failed || (set && found) || (!set && !found)) {
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen if (file_dotlock_delete(&dotlock) < 0) {
602a0434db30d8e3292d1c161a803d96a879a74fTimo Sirainen subsfile_set_syscall_error(list,
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen "file_dotlock_delete()", path);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen failed = TRUE;
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen }
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen } else {
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen enum dotlock_replace_flags flags =
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen DOTLOCK_REPLACE_FLAG_VERIFY_OWNER;
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen if (file_dotlock_replace(&dotlock, flags) < 0) {
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Sirainen subsfile_set_syscall_error(list,
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen "file_dotlock_replace()", path);
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen failed = TRUE;
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen }
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen }
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen return failed ? -1 : 0;
6a170d6d781094bdc75f027b6456dde160fbde39Timo Sirainen}
6a170d6d781094bdc75f027b6456dde160fbde39Timo Sirainen
6a170d6d781094bdc75f027b6456dde160fbde39Timo Sirainenstruct subsfile_list_context *
6a170d6d781094bdc75f027b6456dde160fbde39Timo Sirainensubsfile_list_init(struct mailbox_list *list, const char *path)
1bc075e2e4ed422f9590c95c3ae223422b97ce6aTimo Sirainen{
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainen struct subsfile_list_context *ctx;
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainen pool_t pool;
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainen int fd;
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen pool = pool_alloconly_create("subsfile_list",
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen list->mailbox_name_max_length + 1024);
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen ctx = p_new(pool, struct subsfile_list_context, 1);
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen ctx->pool = pool;
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen ctx->list = list;
a0b6b441fc679e562e79be0fb2819ffc24ab5b74Timo Sirainen
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen fd = nfs_safe_open(path, O_RDONLY);
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen if (fd == -1) {
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen if (errno != ENOENT) {
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainen subsfile_set_syscall_error(list, "open()", path);
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen ctx->failed = TRUE;
6657aee0bb6c603b4ee5111388b93c1a8a9ad680Martti Rannanjärvi }
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen } else {
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen ctx->input =
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen i_stream_create_file(fd, pool,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen list->mailbox_name_max_length+1,
4106a25399703eb6cbb166dcbd5bb932cb2f7ad2Timo Sirainen TRUE);
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen }
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen ctx->path = p_strdup(pool, path);
699fdc186f982f70d990820796eaa0f12133e27cTimo Sirainen return ctx;
699fdc186f982f70d990820796eaa0f12133e27cTimo Sirainen}
699fdc186f982f70d990820796eaa0f12133e27cTimo Sirainen
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainenint subsfile_list_deinit(struct subsfile_list_context *ctx)
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen{
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody int ret = ctx->failed ? -1 : 0;
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody if (ctx->input != NULL)
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody i_stream_destroy(&ctx->input);
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody pool_unref(ctx->pool);
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody return ret;
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody}
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmodyconst char *subsfile_list_next(struct subsfile_list_context *ctx)
573424407a2d3c1453638a643583a7cf10c129e1Phil Carmody{
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody const char *line;
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody unsigned int i;
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody int fd;
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody if (ctx->failed || ctx->input == NULL)
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody return NULL;
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody for (i = 0;; i++) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen line = next_line(ctx->list, ctx->path, ctx->input, &ctx->failed,
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen i < SUBSCRIPTION_FILE_ESTALE_RETRY_COUNT);
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen if (ctx->input->stream_errno != ESTALE ||
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen i == SUBSCRIPTION_FILE_ESTALE_RETRY_COUNT)
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen break;
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen /* Reopen the subscription file and re-send everything.
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen this isn't the optimal behavior, but it's allowed by
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen IMAP and this way we don't have to read everything into
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen memory or try to play any guessing games. */
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen i_stream_destroy(&ctx->input);
4c096615cb86a826fda377b87df22c579bfe5525Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen fd = nfs_safe_open(ctx->path, O_RDONLY);
if (fd == -1) {
/* In case of ENOENT all the subscriptions got lost.
Just return end of subscriptions list in that
case. */
if (errno != ENOENT) {
subsfile_set_syscall_error(ctx->list, "open()",
ctx->path);
ctx->failed = TRUE;
}
return NULL;
}
ctx->input = i_stream_create_file(fd, ctx->pool,
ctx->list->mailbox_name_max_length+1,
TRUE);
}
return line;
}