Exemplo n.º 1
0
int o_stream_nfinish(struct ostream *stream)
{
	o_stream_nflush(stream);
	o_stream_ignore_last_errors(stream);
	errno = stream->last_failed_errno;
	return stream->last_failed_errno != 0 ? -1 : 0;
}
Exemplo n.º 2
0
static int mail_index_recreate(struct mail_index *index)
{
	struct mail_index_map *map = index->map;
	struct ostream *output;
	unsigned int base_size;
	const char *path;
	int ret = 0, fd;

	i_assert(!MAIL_INDEX_IS_IN_MEMORY(index));
	i_assert(map->hdr.indexid == index->indexid);
	i_assert((map->hdr.flags & MAIL_INDEX_HDR_FLAG_CORRUPTED) == 0);
	i_assert(index->indexid != 0);

	fd = mail_index_create_tmp_file(index, index->filepath, &path);
	if (fd == -1)
		return -1;

	output = o_stream_create_fd_file(fd, 0, FALSE);
	o_stream_cork(output);

	base_size = I_MIN(map->hdr.base_header_size, sizeof(map->hdr));
	o_stream_nsend(output, &map->hdr, base_size);
	o_stream_nsend(output, CONST_PTR_OFFSET(map->hdr_base, base_size),
		       map->hdr.header_size - base_size);
	o_stream_nsend(output, map->rec_map->records,
		       map->rec_map->records_count * map->hdr.record_size);
	o_stream_nflush(output);
	if (o_stream_nfinish(output) < 0) {
		mail_index_file_set_syscall_error(index, path, "write()");
		ret = -1;
	}
	o_stream_destroy(&output);

	if (ret == 0 && index->fsync_mode != FSYNC_MODE_NEVER) {
		if (fdatasync(fd) < 0) {
			mail_index_file_set_syscall_error(index, path,
							  "fdatasync()");
			ret = -1;
		}
	}

	if (close(fd) < 0) {
		mail_index_file_set_syscall_error(index, path, "close()");
		ret = -1;
	}

	if ((index->flags & MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS) != 0)
		(void)mail_index_create_backup(index);

	if (ret == 0 && rename(path, index->filepath) < 0) {
		mail_index_set_error(index, "rename(%s, %s) failed: %m",
				     path, index->filepath);
		ret = -1;
	}

	if (ret < 0)
		i_unlink(path);
	return ret;
}
Exemplo n.º 3
0
static int
cmd_setmetadata_entry(struct imap_setmetadata_context *ctx,
                      const char *entry_name,
                      const struct imap_arg *entry_value)
{
    struct istream *inputs[2];
    struct mail_attribute_value value;
    string_t *path;
    int ret;

    switch (entry_value->type) {
    case IMAP_ARG_NIL:
    case IMAP_ARG_ATOM:
    case IMAP_ARG_STRING:
        /* we have the value already */
        if (ctx->failed)
            return 1;
        memset(&value, 0, sizeof(value));
        value.value = imap_arg_as_nstring(entry_value);
        ret = imap_metadata_set(ctx->trans, entry_name, &value);
        if (ret < 0) {
            /* delay reporting the failure so we'll finish
               reading the command input */
            ctx->storage_failure = TRUE;
            ctx->failed = TRUE;
        }
        return 1;
    case IMAP_ARG_LITERAL_SIZE:
        o_stream_nsend(ctx->cmd->client->output, "+ OK\r\n", 6);
        o_stream_nflush(ctx->cmd->client->output);
        o_stream_uncork(ctx->cmd->client->output);
        o_stream_cork(ctx->cmd->client->output);
    /* fall through */
    case IMAP_ARG_LITERAL_SIZE_NONSYNC:
        i_free(ctx->entry_name);
        ctx->entry_name = i_strdup(entry_name);
        ctx->entry_value_len = imap_arg_as_literal_size(entry_value);

        inputs[0] = i_stream_create_limit(ctx->cmd->client->input,
                                          ctx->entry_value_len);
        inputs[1] = NULL;

        path = t_str_new(128);
        mail_user_set_get_temp_prefix(path, ctx->cmd->client->user->set);
        ctx->input = i_stream_create_seekable_path(inputs,
                     METADATA_MAX_INMEM_SIZE, str_c(path));
        i_stream_set_name(ctx->input, i_stream_get_name(inputs[0]));
        i_stream_unref(&inputs[0]);
        return cmd_setmetadata_entry_read_stream(ctx);
    case IMAP_ARG_LITERAL:
    case IMAP_ARG_LIST:
    case IMAP_ARG_EOL:
        break;
    }
    i_unreached();
}
Exemplo n.º 4
0
static bool cmd_append_send_literal_continue(struct cmd_append_context *ctx)
{
	if (ctx->failed) {
		/* tagline was already sent, we can abort here */
		return FALSE;
	}

	o_stream_nsend(ctx->client->output, "+ OK\r\n", 6);
	o_stream_nflush(ctx->client->output);
	o_stream_uncork(ctx->client->output);
	o_stream_cork(ctx->client->output);
	return TRUE;
}
Exemplo n.º 5
0
static void client_send_sendalive_if_needed(struct client *client)
{
	time_t now, last_io;

	if (o_stream_get_buffer_used_size(client->output) != 0)
		return;

	now = time(NULL);
	last_io = I_MAX(client->last_input, client->last_output);
	if (now - last_io > MAIL_STORAGE_STAYALIVE_SECS) {
		o_stream_nsend_str(client->output, "* OK Hang in there..\r\n");
		o_stream_nflush(client->output);
		client->last_output = now;
	}
}
Exemplo n.º 6
0
void client_disconnect(struct client *client, const char *reason)
{
	i_assert(reason != NULL);

	if (client->disconnected)
		return;

	i_info("Disconnected: %s %s", reason, client_stats(client));
	client->disconnected = TRUE;
	o_stream_nflush(client->output);
	o_stream_uncork(client->output);

	i_stream_close(client->input);
	o_stream_close(client->output);

	if (client->to_idle != NULL)
		timeout_remove(&client->to_idle);
	client->to_idle = timeout_add(0, client_destroy_timeout, client);
}
Exemplo n.º 7
0
static int imap_parser_literal_end(struct imap_parser *parser)
{
	if ((parser->flags & IMAP_PARSE_FLAG_LITERAL_SIZE) == 0) {
		if (parser->line_size >= parser->max_line_size ||
		    parser->literal_size >
		    parser->max_line_size - parser->line_size) {
			/* too long string, abort. */
			parser->error = "Literal size too large";
			parser->fatal_error = TRUE;
			return FALSE;
		}

		if (parser->output != NULL && !parser->literal_nonsync) {
			o_stream_nsend(parser->output, "+ OK\r\n", 6);
			o_stream_nflush(parser->output);
		}
	}

	parser->cur_type = ARG_PARSE_LITERAL_DATA;
	parser->literal_skip_crlf = TRUE;

	parser->cur_pos = 0;
	return TRUE;
}