static struct auth_master_reply *
fill_reply(const struct user_data *user, size_t *reply_size)
{
- struct auth_master_reply *reply;
+ struct auth_master_reply reply, *reply_p;
buffer_t *buf;
char *p;
buf = buffer_create_dynamic(data_stack_pool,
- sizeof(*reply) + 256, (size_t)-1);
- reply = buffer_append_space(buf, sizeof(*reply));
+ sizeof(reply) + 256, (size_t)-1);
+ memset(&reply, 0, sizeof(reply));
+ buffer_append(buf, &reply, sizeof(reply));
- reply->success = TRUE;
+ reply.success = TRUE;
- reply->uid = user->uid;
- reply->gid = user->gid;
+ reply.uid = user->uid;
+ reply.gid = user->gid;
- reply->system_user_idx = reply_add(buf, user->system_user);
- reply->virtual_user_idx = reply_add(buf, user->virtual_user);
- reply->mail_idx = reply_add(buf, user->mail);
+ reply.system_user_idx = reply_add(buf, user->system_user);
+ reply.virtual_user_idx = reply_add(buf, user->virtual_user);
+ reply.mail_idx = reply_add(buf, user->mail);
p = strstr(user->home, "/./");
if (p == NULL) {
- reply->home_idx = reply_add(buf, user->home);
- reply->chroot_idx = reply_add(buf, NULL);
+ reply.home_idx = reply_add(buf, user->home);
+ reply.chroot_idx = reply_add(buf, NULL);
} else {
/* wu-ftpd like <chroot>/./<home> */
- reply->chroot_idx = reply_add(buf, t_strdup_until(user->home, p));
- reply->home_idx = reply_add(buf, p + 3);
+ reply.chroot_idx =
+ reply_add(buf, t_strdup_until(user->home, p));
+ reply.home_idx = reply_add(buf, p + 3);
}
*reply_size = buffer_get_used_size(buf);
- reply->data_size = *reply_size - sizeof(*reply);
- return reply;
+ reply.data_size = *reply_size - sizeof(reply);
+
+ reply_p = buffer_get_space_unsafe(buf, 0, sizeof(reply));
+ *reply_p = reply;
+
+ return reply_p;
}
static void send_reply(struct auth_master_reply *reply, size_t reply_size,
void command_register(const char *name, command_func_t *func)
{
- struct command *cmd;
+ struct command cmd;
- cmd = buffer_append_space(cmdbuf, sizeof(*cmd));
- cmd->name = name;
- cmd->func = func;
+ cmd.name = name;
+ cmd.func = func;
+ buffer_append(cmdbuf, &cmd, sizeof(cmd));
cmdbuf_unsorted = TRUE;
}
if (ctx->common_mask != 0)
mail_sort_check_flush(ctx, mail);
- buf = buffer_append_space(ctx->sort_buffer, ctx->sort_element_size);
+ buf = buffer_append_space_unsafe(ctx->sort_buffer,
+ ctx->sort_element_size);
id = ctx->id_is_uid ? mail->uid : mail->seq;
memcpy(buf, &id, sizeof(id)); pos = sizeof(id);
size = destleft;
srcleft = *src_size;
ic_srcbuf = (ICONV_CONST char *) src;
- ic_destbuf = buffer_append_space(dest, destleft);
+ ic_destbuf = buffer_append_space_unsafe(dest, destleft);
if (iconv(t->cd, &ic_srcbuf, &srcleft,
&ic_destbuf, &destleft) != (size_t)-1)
char *destbuf;
size_t i;
- destbuf = buffer_get_space(dest, destpos, src_size);
+ destbuf = buffer_get_space_unsafe(dest, destpos, src_size);
for (i = 0; i < src_size; i++)
destbuf[i] = i_toupper(src[i]); /* FIXME: utf8 */
}
static void *create_data_block(struct mail_index_update *update,
size_t data_size, size_t extra_size)
{
- struct mail_index_data_record_header *dest_hdr;
- struct mail_index_data_record *rec, *destrec;
+ struct mail_index_data_record *rec, destrec;
enum mail_data_field field;
buffer_t *buf;
const void *src;
- size_t src_size;
- size_t full_field_size;
+ size_t src_size, filler_size;
int i;
i_assert(data_size <= UINT_MAX);
buf = buffer_create_static_hard(update->pool, data_size);
/* set header */
- dest_hdr = buffer_append_space(buf, sizeof(*dest_hdr));
- memcpy(dest_hdr, &update->data_hdr, sizeof(*dest_hdr));
- dest_hdr->data_size = data_size;
+ update->data_hdr.data_size = data_size;
+ buffer_append(buf, &update->data_hdr, sizeof(update->data_hdr));
/* set fields */
rec = mail_index_data_lookup(update->index->data, update->rec, 0);
for (i = 0, field = 1; field != DATA_FIELD_LAST; i++, field <<= 1) {
if (update->fields[i] != NULL) {
/* value was modified - use it */
- full_field_size =
+ destrec.full_field_size =
get_max_align_size(update->field_sizes[i],
update->field_extra_sizes[i],
&extra_size);
src_size = update->field_sizes[i];
} else if (rec != NULL && rec->field == field) {
/* use the old value */
- full_field_size = rec->full_field_size;
+ destrec.full_field_size = rec->full_field_size;
src = rec->data;
src_size = rec->full_field_size;
} else {
/* the field doesn't exist, jump to next */
continue;
}
- i_assert((full_field_size % INDEX_ALIGN_SIZE) == 0);
+ i_assert((destrec.full_field_size % INDEX_ALIGN_SIZE) == 0);
- destrec = buffer_append_space(buf, SIZEOF_MAIL_INDEX_DATA +
- full_field_size);
- destrec->field = field;
- destrec->full_field_size = full_field_size;
- memcpy(destrec->data, src, src_size);
+ destrec.field = field;
+ buffer_append(buf, &destrec, SIZEOF_MAIL_INDEX_DATA);
+ buffer_append(buf, src, src_size);
+
+ filler_size = destrec.full_field_size - src_size;
+ if (filler_size != 0) {
+ buffer_set_used_size(buf, buffer_get_used_size(buf) +
+ filler_size);
+ }
if (rec != NULL && rec->field == field) {
rec = mail_index_data_next(update->index->data,
unsigned int *expunges_before)
{
struct modify_log_record *rec;
- struct modify_log_expunge *expunge;
+ struct modify_log_expunge expunge, *expunges;
buffer_t *buf;
size_t count;
unsigned int before, max_records;
return NULL;
}
- expunge = buffer_append_space(buf, sizeof(*expunge));
-
if (rec->seq1 < first_seq) {
/* partial initial match, update
before-counter */
before += first_seq - rec->seq1;
- expunge->seq_count = rec->seq2 - first_seq + 1;
+ expunge.seq_count = rec->seq2 - first_seq + 1;
} else {
- expunge->seq_count = rec->seq2 - rec->seq1 + 1;
+ expunge.seq_count = rec->seq2 - rec->seq1 + 1;
}
- expunge->uid1 = rec->uid1;
- expunge->uid2 = rec->uid2;
+ expunge.uid1 = rec->uid1;
+ expunge.uid2 = rec->uid2;
+ buffer_append(buf, &expunge, sizeof(expunge));
}
if (rec->seq1 <= last_seq) {
}
/* terminate the array */
- expunge = buffer_append_space(buf, sizeof(*expunge));
- memset(expunge, 0, sizeof(*expunge));
+ buffer_set_used_size(buf, buffer_get_used_size(buf) + sizeof(expunge));
/* extract the array from buffer */
- count = buffer_get_used_size(buf)/sizeof(struct modify_log_expunge);
- expunge = buffer_free_without_data(buf);
+ count = buffer_get_used_size(buf) / sizeof(expunge);
+ expunges = buffer_free_without_data(buf);
/* sort the UID array, not including the terminating 0 */
- qsort(expunge, count-1, sizeof(struct modify_log_expunge),
- compare_expunge);
+ qsort(expunges, count-1, sizeof(expunge), compare_expunge);
*expunges_before = before;
- return expunge;
+ return expunges;
}
const struct modify_log_expunge *
/* pretty much copy&pasted from sequence code above ..
kind of annoying */
struct modify_log_record *rec;
- struct modify_log_expunge *expunge;
+ struct modify_log_expunge expunge, *expunges;
buffer_t *buf;
size_t count;
unsigned int before, max_records;
return NULL;
}
- expunge = buffer_append_space(buf, sizeof(*expunge));
-
- expunge->uid1 = rec->uid1;
- expunge->uid2 = rec->uid2;
- expunge->seq_count = rec->seq2 -rec->seq1 + 1;
+ expunge.uid1 = rec->uid1;
+ expunge.uid2 = rec->uid2;
+ expunge.seq_count = rec->seq2 -rec->seq1 + 1;
+ buffer_append(buf, &expunge, sizeof(expunge));
}
}
/* terminate the array */
- expunge = buffer_append_space(buf, sizeof(*expunge));
- memset(expunge, 0, sizeof(*expunge));
+ buffer_set_used_size(buf, buffer_get_used_size(buf) + sizeof(expunge));
/* extract the array from buffer */
- count = buffer_get_used_size(buf) / sizeof(struct modify_log_expunge);
- expunge = buffer_free_without_data(buf);
+ count = buffer_get_used_size(buf) / sizeof(expunge);
+ expunges = buffer_free_without_data(buf);
/* sort the UID array, not including the terminating 0 */
- qsort(expunge, count-1, sizeof(struct modify_log_expunge),
- compare_expunge);
+ qsort(expunges, count-1, sizeof(expunge), compare_expunge);
*expunges_before = before;
- return expunge;
+ return expunges;
}
static unsigned int
static void mbox_parse_imapbase(const unsigned char *value, size_t len,
struct mbox_header_context *ctx)
{
- const char **flag, *str;
+ const char *flag, *str;
char *end;
buffer_t *buf;
size_t pos, start;
/* we're at the 3rd field now, which begins the list of custom flags */
buf = buffer_create_dynamic(data_stack_pool,
- MAIL_CUSTOM_FLAGS_COUNT, MAX_CUSTOM_FLAGS);
+ MAIL_CUSTOM_FLAGS_COUNT *
+ sizeof(const char *),
+ MAX_CUSTOM_FLAGS * sizeof(const char *));
for (start = pos; ; pos++) {
if (pos == len || value[pos] == ' ' || value[pos] == '\t') {
if (start != pos) {
- flag = buffer_append_space(buf, sizeof(*flag));
- if (flag == NULL)
+ flag = t_strdup_until(value+start, value+pos);
+ if (buffer_append(buf, flag, sizeof(flag)) == 0)
break;
-
- *flag = t_strdup_until(value+start, value+pos);
}
start = pos+1;
flags = MAIL_CUSTOM_FLAGS_MASK;
count = buffer_get_used_size(buf) / sizeof(const char *);
- flag = buffer_free_without_data(buf);
ret = mail_custom_flags_fix_list(ctx->index->custom_flags, &flags,
- flag, count);
+ buffer_free_without_data(buf), count);
t_pop();
}
static unsigned int
_message_part_serialize(struct message_part *part, buffer_t *dest)
{
- struct serialized_message_part *spart;
- unsigned int count = 0;
+ struct serialized_message_part spart, *spart_p;
+ unsigned int count, children_count;
+ size_t pos;
+ count = 0;
while (part != NULL) {
/* create serialized part */
- spart = buffer_append_space(dest, sizeof(*spart));
- memset(spart, 0, sizeof(*spart));
+ memset(&spart, 0, sizeof(spart));
- spart->physical_pos = part->physical_pos;
+ spart.physical_pos = part->physical_pos;
- spart->header_physical_size = part->header_size.physical_size;
- spart->header_virtual_size = part->header_size.virtual_size;
- spart->header_lines = part->header_size.lines;
+ spart.header_physical_size = part->header_size.physical_size;
+ spart.header_virtual_size = part->header_size.virtual_size;
+ spart.header_lines = part->header_size.lines;
- spart->body_physical_size = part->body_size.physical_size;
- spart->body_virtual_size = part->body_size.virtual_size;
- spart->body_lines = part->body_size.lines;
+ spart.body_physical_size = part->body_size.physical_size;
+ spart.body_virtual_size = part->body_size.virtual_size;
+ spart.body_lines = part->body_size.lines;
- spart->flags = part->flags;
+ spart.flags = part->flags;
+ buffer_append(dest, &spart, sizeof(spart));
if (part->children != NULL) {
- spart->children_count =
+ pos = buffer_get_used_size(dest) - sizeof(spart);
+ children_count =
_message_part_serialize(part->children, dest);
+
+ /* note that we can't just save the pointer to
+ our appended spart since it may change after
+ child-appends have realloc()ed buffer memory. */
+ spart_p = buffer_get_space_unsafe(dest, pos,
+ sizeof(spart));
+ spart_p->children_count = children_count;
}
count++;
src, src_pos, copy_size);
}
-void *buffer_get_space(buffer_t *buf, size_t pos, size_t size)
+void *buffer_get_space_unsafe(buffer_t *buf, size_t pos, size_t size)
{
if (!buffer_check_write(buf, &pos, &size, FALSE))
return NULL;
return buf->w_buffer + pos;
}
-void *buffer_append_space(buffer_t *buf, size_t size)
+void *buffer_append_space_unsafe(buffer_t *buf, size_t size)
{
- return buffer_get_space(buf, buf->used - buf->start_pos, size);
+ return buffer_get_space_unsafe(buf, buf->used - buf->start_pos, size);
}
const void *buffer_get_data(const buffer_t *buf, size_t *used_size)
#ifndef __BUFFER_H
#define __BUFFER_H
+/* WARNING: Be careful with functions that return pointers to data.
+ With dynamic buffers they are valid only as long as buffer is not
+ realloc()ed. You shouldn't rely on it being valid if you have modified
+ buffer in any way. */
+
/* Create a static sized buffer. Writes past this size will simply not
succeed. */
buffer_t *buffer_create_static(pool_t pool, size_t size);
size_t src_pos, size_t copy_size);
/* Returns pointer to specified position in buffer, or NULL if there's not
- enough space. */
-void *buffer_get_space(buffer_t *buf, size_t pos, size_t size);
+ enough space. WARNING: The returned address may become invalid if you add
+ more data to buffer. */
+void *buffer_get_space_unsafe(buffer_t *buf, size_t pos, size_t size);
/* Increase the buffer usage by given size, and return a pointer to beginning
of it, or NULL if there's not enough space in buffer. */
-void *buffer_append_space(buffer_t *buf, size_t size);
+void *buffer_append_space_unsafe(buffer_t *buf, size_t size);
/* Returns pointer to beginning of buffer data. Current used size of buffer is
stored in used_size if it's non-NULL. */
const void *buffer_get_data(const buffer_t *buf, size_t *used_size);
/* Like buffer_get_data(), but don't return it as const. Returns NULL if the
- buffer is non-modifyable. */
+ buffer is non-modifyable. WARNING: The returned address may become invalid
+ if you add more data to buffer. */
void *buffer_get_modifyable_data(const buffer_t *buf, size_t *used_size);
/* Set the "used size" of buffer, ie. 0 would set the buffer empty.
fmt = printf_string_fix_format(fmt);
append_len = printf_string_upper_bound(fmt, args);
- buf = buffer_append_space(str, append_len);
+ buf = buffer_append_space_unsafe(str, append_len);
#ifdef HAVE_VSNPRINTF
ret = vsnprintf(buf, append_len, fmt, args2);