changeset 833:41ec8cadd238 HEAD

Replaced TempString with a String which can use any memory pool and uses Buffer internally.
author Timo Sirainen <tss@iki.fi>
date Sun, 22 Dec 2002 00:02:57 +0200
parents e1ca4ef76ab4
children 64a7dc694b60
files src/auth/auth-digest-md5.c src/imap/cmd-select.c src/imap/cmd-status.c src/imap/commands-util.c src/lib-imap/imap-bodystructure.c src/lib-imap/imap-envelope.c src/lib-imap/imap-envelope.h src/lib-imap/imap-message-cache.c src/lib-imap/imap-quote.c src/lib-imap/imap-util.c src/lib-index/maildir/maildir-index.c src/lib-index/mbox/mbox-from.c src/lib-index/mbox/mbox-rewrite.c src/lib-mail/rfc822-address.c src/lib-storage/index/index-fetch-section.c src/lib-storage/index/index-fetch.c src/lib-storage/index/index-fetch.h src/lib/Makefile.am src/lib/lib.h src/lib/str.c src/lib/str.h src/lib/strfuncs.h src/lib/temp-string.c src/lib/temp-string.h src/login/client-authenticate.c src/master/imap-process.c
diffstat 26 files changed, 548 insertions(+), 557 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/auth-digest-md5.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/auth/auth-digest-md5.c	Sun Dec 22 00:02:57 2002 +0200
@@ -8,7 +8,7 @@
 #include "hex-binary.h"
 #include "md5.h"
 #include "randgen.h"
-#include "temp-string.h"
+#include "str.h"
 
 #include "auth.h"
 #include "cookie.h"
@@ -57,7 +57,7 @@
 
 static const char *get_digest_challenge(AuthData *auth)
 {
-	TempString *qoplist, *realms;
+	String *qoplist, *realms;
 	Buffer *buf;
 	char *const *tmp;
 	unsigned char nonce[16];
@@ -86,24 +86,24 @@
 	t_pop();
 
 	/* get list of allowed QoPs */
-	qoplist = t_string_new(32);
+	qoplist = t_str_new(32);
 	for (i = 0; i < QOP_COUNT; i++) {
 		if (auth->qop & (1 << i)) {
-			if (qoplist->len > 0)
-				t_string_append_c(qoplist, ',');
-			t_string_append(qoplist, qop_names[i]);
+			if (str_len(qoplist) > 0)
+				str_append_c(qoplist, ',');
+			str_append(qoplist, qop_names[i]);
 		}
 	}
 
-	realms = t_string_new(128);
+	realms = t_str_new(128);
 	for (tmp = auth_realms; *tmp != NULL; tmp++) {
-		t_string_printfa(realms, "realm=\"%s\"", *tmp);
-		t_string_append_c(realms, ',');
+		str_printfa(realms, "realm=\"%s\"", *tmp);
+		str_append_c(realms, ',');
 	}
 
-	return t_strconcat(realms->str,
+	return t_strconcat(str_c(realms),
 			   "nonce=\"", auth->nonce, "\",",
-			   "qop-options=\"", qoplist->str, "\",",
+			   "qop-options=\"", str_c(qoplist), "\",",
 			   "charset=\"utf-8\",",
 			   "algorithm=\"md5-sess\"",
 			   NULL);
--- a/src/imap/cmd-select.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/imap/cmd-select.c	Sun Dec 22 00:02:57 2002 +0200
@@ -1,7 +1,6 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "common.h"
-#include "temp-string.h"
 #include "commands.h"
 
 int _cmd_select_full(Client *client, int readonly)
--- a/src/imap/cmd-status.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/imap/cmd-status.c	Sun Dec 22 00:02:57 2002 +0200
@@ -1,7 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "common.h"
-#include "temp-string.h"
+#include "str.h"
 #include "commands.h"
 
 /* Returns status items, or -1 if error */
@@ -82,7 +82,7 @@
 	MailboxStatus status;
 	MailboxStatusItems items;
 	const char *mailbox;
-	TempString *str;
+	String *str;
 
 	/* <mailbox> <status items> */
 	if (!client_read_args(client, 2, 0, &args))
@@ -107,24 +107,24 @@
 		return TRUE;
 	}
 
-	str = t_string_new(128);
-	t_string_printfa(str, "* STATUS %s (", mailbox);
+	str = t_str_new(128);
+	str_printfa(str, "* STATUS %s (", mailbox);
 	if (items & STATUS_MESSAGES)
-		t_string_printfa(str, "MESSAGES %u ", status.messages);
+		str_printfa(str, "MESSAGES %u ", status.messages);
 	if (items & STATUS_RECENT)
-		t_string_printfa(str, "RECENT %u ", status.recent);
+		str_printfa(str, "RECENT %u ", status.recent);
 	if (items & STATUS_UIDNEXT)
-		t_string_printfa(str, "UIDNEXT %u ", status.uidnext);
+		str_printfa(str, "UIDNEXT %u ", status.uidnext);
 	if (items & STATUS_UIDVALIDITY)
-		t_string_printfa(str, "UIDVALIDITY %u ", status.uidvalidity);
+		str_printfa(str, "UIDVALIDITY %u ", status.uidvalidity);
 	if (items & STATUS_UNSEEN)
-		t_string_printfa(str, "UNSEEN %u ", status.unseen);
+		str_printfa(str, "UNSEEN %u ", status.unseen);
 
-	if (str->str[str->len-1] == ' ')
-		t_string_truncate(str, str->len-1);
-	t_string_append_c(str, ')');
+	if (items != 0)
+		str_truncate(str, str_len(str)-1);
+	str_append_c(str, ')');
 
-	client_send_line(client, str->str);
+	client_send_line(client, str_c(str));
 	client_send_tagline(client, "OK Status completed.");
 
 	return TRUE;
--- a/src/imap/commands-util.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/imap/commands-util.c	Sun Dec 22 00:02:57 2002 +0200
@@ -1,7 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "common.h"
-#include "temp-string.h"
+#include "str.h"
 #include "commands-util.h"
 #include "imap-util.h"
 
@@ -176,7 +176,7 @@
 static const char *get_custom_flags_string(const char *custom_flags[],
 					   unsigned int custom_flags_count)
 {
-	TempString *str;
+	String *str;
 	unsigned int i;
 
 	/* first see if there even is custom flags */
@@ -188,14 +188,14 @@
 	if (i == custom_flags_count)
 		return "";
 
-	str = t_string_new(256);
+	str = t_str_new(256);
 	for (; i < custom_flags_count; i++) {
 		if (custom_flags[i] != NULL) {
-			t_string_append_c(str, ' ');
-			t_string_append(str, custom_flags[i]);
+			str_append_c(str, ' ');
+			str_append(str, custom_flags[i]);
 		}
 	}
-	return str->str;
+	return str_c(str);
 }
 
 #define SYSTEM_FLAGS "\\Answered \\Flagged \\Deleted \\Seen \\Draft"
--- a/src/lib-imap/imap-bodystructure.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-imap/imap-bodystructure.c	Sun Dec 22 00:02:57 2002 +0200
@@ -2,7 +2,7 @@
 
 #include "lib.h"
 #include "istream.h"
-#include "temp-string.h"
+#include "str.h"
 #include "rfc822-tokenize.h"
 #include "message-parser.h"
 #include "message-content-parser.h"
@@ -16,7 +16,7 @@
 
 typedef struct {
 	Pool pool;
-	TempString *str;
+	String *str;
 	char *content_type, *content_subtype;
 	char *content_type_params;
 	char *content_transfer_encoding;
@@ -30,7 +30,7 @@
 	MessagePartEnvelopeData *envelope;
 } MessagePartBodyData;
 
-static void part_write_bodystructure(MessagePart *part, TempString *str,
+static void part_write_bodystructure(MessagePart *part, String *str,
 				     int extended);
 
 static void parse_content_type(const Rfc822Token *tokens,
@@ -60,15 +60,15 @@
         MessagePartBodyData *data = context;
 	const char *str;
 
-	if (data->str->len != 0)
-		t_string_append_c(data->str, ' ');
+	if (str_len(data->str) != 0)
+		str_append_c(data->str, ' ');
 
-	t_string_append_c(data->str, '"');
-	t_string_append_n(data->str, name->ptr, name->len);
-	t_string_append(data->str, "\" ");
+	str_append_c(data->str, '"');
+	str_append_n(data->str, name->ptr, name->len);
+	str_append(data->str, "\" ");
 
         str = rfc822_tokens_get_value_quoted(value, value_count);
-	t_string_append(data->str, str);
+	str_append(data->str, str);
 }
 
 static void parse_content_transfer_encoding(const Rfc822Token *tokens,
@@ -95,7 +95,7 @@
 				   int count, void *context)
 {
         MessagePartBodyData *data = context;
-	TempString *str;
+	String *str;
 	int quoted;
 
 	/* Content-Language: en-US, az-arabic (comments allowed) */
@@ -103,7 +103,7 @@
 	if (count <= 0)
 		return;
 
-	str = t_string_new(256);
+	str = t_str_new(256);
 
 	quoted = FALSE;
 	for (; count > 0; count--, tokens++) {
@@ -114,7 +114,7 @@
 		case ',':
 			/* list separator */
 			if (quoted) {
-				t_string_append_c(str, '"');
+				str_append_c(str, '"');
 				quoted = FALSE;
 			}
 			break;
@@ -123,26 +123,24 @@
 			   and '-' is allowed, so anything else is error
 			   which we can deal with however we want. */
 			if (!quoted) {
-				if (str->len > 0)
-					t_string_append_c(str, ' ');
-				t_string_append_c(str, '"');
+				if (str_len(str) > 0)
+					str_append_c(str, ' ');
+				str_append_c(str, '"');
 				quoted = TRUE;
 			}
 
-			if (IS_TOKEN_STRING(tokens->token)) {
-				t_string_append_n(str, tokens->ptr,
-						  tokens->len);
-			} else {
-				t_string_append_c(str, tokens->token);
-			}
+			if (IS_TOKEN_STRING(tokens->token))
+				str_append_n(str, tokens->ptr, tokens->len);
+			else
+				str_append_c(str, tokens->token);
 			break;
 		}
 	}
 
 	if (quoted)
-		t_string_append_c(str, '"');
+		str_append_c(str, '"');
 
-	data->content_language = p_strdup(data->pool, str->str);
+	data->content_language = p_strdup(data->pool, str_c(str));
 }
 
 static void parse_header(MessagePart *part,
@@ -175,13 +173,13 @@
 
 	if (strcasecmp(name, "Content-Type") == 0 &&
 	    part_data->content_type == NULL) {
-		part_data->str = t_string_new(256);
+		part_data->str = t_str_new(256);
 		(void)message_content_parse_header(t_strndup(value, value_len),
 						   parse_content_type,
 						   parse_save_params_list,
 						   part_data);
 		part_data->content_type_params =
-			p_strdup(pool, part_data->str->str);
+			p_strdup(pool, str_c(part_data->str));
 	} else if (strcasecmp(name, "Content-Transfer-Encoding") == 0 &&
 		   part_data->content_transfer_encoding == NULL) {
 		(void)message_content_parse_header(t_strndup(value, value_len),
@@ -197,13 +195,13 @@
 			imap_quote_value(pool, value, value_len);
 	} else if (strcasecmp(name, "Content-Disposition") == 0 &&
 		   part_data->content_disposition_params == NULL) {
-		part_data->str = t_string_new(256);
+		part_data->str = t_str_new(256);
 		(void)message_content_parse_header(t_strndup(value, value_len),
 						   parse_content_disposition,
 						   parse_save_params_list,
 						   part_data);
 		part_data->content_disposition_params =
-			p_strdup(pool, part_data->str->str);
+			p_strdup(pool, str_c(part_data->str));
 	} else if (strcasecmp(name, "Content-Language") == 0) {
 		(void)message_content_parse_header(t_strndup(value, value_len),
 						   parse_content_language, NULL,
@@ -241,7 +239,7 @@
 	}
 }
 
-static void part_write_body_multipart(MessagePart *part, TempString *str,
+static void part_write_body_multipart(MessagePart *part, String *str,
 				      int extended)
 {
 	MessagePartBodyData *data = part->context;
@@ -257,53 +255,53 @@
 		/* no parts in multipart message,
 		   that's not allowed. write a single
 		   0-length text/plain structure */
-		t_string_append(str, EMPTY_BODYSTRUCTURE);
+		str_append(str, EMPTY_BODYSTRUCTURE);
 	}
 
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	if (data->content_subtype != NULL)
-		t_string_append(str, data->content_subtype);
+		str_append(str, data->content_subtype);
 	else
-		t_string_append(str, "x-unknown");
+		str_append(str, "x-unknown");
 
 	if (!extended)
 		return;
 
 	/* BODYSTRUCTURE data */
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	if (data->content_type_params == NULL)
-		t_string_append(str, "NIL");
+		str_append(str, "NIL");
 	else {
-		t_string_append_c(str, '(');
-		t_string_append(str, data->content_type_params);
-		t_string_append_c(str, ')');
+		str_append_c(str, '(');
+		str_append(str, data->content_type_params);
+		str_append_c(str, ')');
 	}
 
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	if (data->content_disposition == NULL)
-		t_string_append(str, "NIL");
+		str_append(str, "NIL");
 	else {
-		t_string_append_c(str, '(');
-		t_string_append(str, data->content_disposition);
+		str_append_c(str, '(');
+		str_append(str, data->content_disposition);
 		if (data->content_disposition_params != NULL) {
-			t_string_append(str, " (");
-			t_string_append(str, data->content_disposition_params);
-			t_string_append_c(str, ')');
+			str_append(str, " (");
+			str_append(str, data->content_disposition_params);
+			str_append_c(str, ')');
 		}
-		t_string_append_c(str, ')');
+		str_append_c(str, ')');
 	}
 
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	if (data->content_language == NULL)
-		t_string_append(str, "NIL");
+		str_append(str, "NIL");
 	else {
-		t_string_append_c(str, '(');
-		t_string_append(str, data->content_language);
-		t_string_append_c(str, ')');
+		str_append_c(str, '(');
+		str_append(str, data->content_language);
+		str_append_c(str, ')');
 	}
 }
 
-static void part_write_body(MessagePart *part, TempString *str, int extended)
+static void part_write_body(MessagePart *part, String *str, int extended)
 {
 	MessagePartBodyData *data = part->context;
 
@@ -313,29 +311,29 @@
 	}
 
 	/* "content type" "subtype" */
-	t_string_append(str, NVL(data->content_type, "\"text\""));
-	t_string_append_c(str, ' ');
-	t_string_append(str, NVL(data->content_subtype, "\"plain\""));
+	str_append(str, NVL(data->content_type, "\"text\""));
+	str_append_c(str, ' ');
+	str_append(str, NVL(data->content_subtype, "\"plain\""));
 
 	/* ("content type param key" "value" ...) */
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	if (data->content_type_params == NULL)
-		t_string_append(str, "NIL");
+		str_append(str, "NIL");
 	else {
-		t_string_append_c(str, '(');
-		t_string_append(str, data->content_type_params);
-		t_string_append_c(str, ')');
+		str_append_c(str, '(');
+		str_append(str, data->content_type_params);
+		str_append_c(str, ')');
 	}
 
-	t_string_printfa(str, " %s %s %s %"PRIuUOFF_T,
-			 NVL(data->content_id, "NIL"),
-			 NVL(data->content_description, "NIL"),
-			 NVL(data->content_transfer_encoding, "\"8bit\""),
-			 part->body_size.virtual_size);
+	str_printfa(str, " %s %s %s %"PRIuUOFF_T,
+		    NVL(data->content_id, "NIL"),
+		    NVL(data->content_description, "NIL"),
+		    NVL(data->content_transfer_encoding, "\"8bit\""),
+		    part->body_size.virtual_size);
 
 	if (part->flags & MESSAGE_PART_FLAG_TEXT) {
 		/* text/.. contains line count */
-		t_string_printfa(str, " %u", part->body_size.lines);
+		str_printfa(str, " %u", part->body_size.lines);
 	} else if (part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) {
 		/* message/rfc822 contains envelope + body + line count */
 		MessagePartBodyData *child_data;
@@ -345,19 +343,19 @@
 
                 child_data = part->children->context;
 
-		t_string_append_c(str, ' ');
+		str_append_c(str, ' ');
 		if (child_data != NULL && child_data->envelope != NULL) {
-			t_string_append_c(str, '(');
+			str_append_c(str, '(');
 			imap_envelope_write_part_data(child_data->envelope,
 						      str);
-			t_string_append_c(str, ')');
+			str_append_c(str, ')');
 		} else {
 			/* buggy message */
-			t_string_append(str, "NIL");
+			str_append(str, "NIL");
 		}
-		t_string_append_c(str, ' ');
+		str_append_c(str, ' ');
 		part_write_bodystructure(part->children, str, extended);
-		t_string_printfa(str, " %u", part->body_size.lines);
+		str_printfa(str, " %u", part->body_size.lines);
 	}
 
 	if (!extended)
@@ -367,42 +365,42 @@
 
 	/* "md5" ("content disposition" ("disposition" "params"))
 	   ("body" "language" "params") */
-	t_string_append_c(str, ' ');
-	t_string_append(str, NVL(data->content_md5, "NIL"));
+	str_append_c(str, ' ');
+	str_append(str, NVL(data->content_md5, "NIL"));
 
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	if (data->content_disposition == NULL)
-		t_string_append(str, "NIL");
+		str_append(str, "NIL");
 	else {
-		t_string_append_c(str, '(');
-		t_string_append(str, data->content_disposition);
-		t_string_append_c(str, ')');
+		str_append_c(str, '(');
+		str_append(str, data->content_disposition);
+		str_append_c(str, ')');
 
 		if (data->content_disposition_params != NULL) {
-			t_string_append(str, " (");
-			t_string_append(str, data->content_disposition_params);
-			t_string_append_c(str, ')');
+			str_append(str, " (");
+			str_append(str, data->content_disposition_params);
+			str_append_c(str, ')');
 		}
 	}
 
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	if (data->content_language == NULL)
-		t_string_append(str, "NIL");
+		str_append(str, "NIL");
 	else {
-		t_string_append_c(str, '(');
-		t_string_append(str, data->content_language);
-		t_string_append_c(str, ')');
+		str_append_c(str, '(');
+		str_append(str, data->content_language);
+		str_append_c(str, ')');
 	}
 }
 
-static void part_write_bodystructure(MessagePart *part, TempString *str,
+static void part_write_bodystructure(MessagePart *part, String *str,
 				     int extended)
 {
 	i_assert(part->parent != NULL || part->next == NULL);
 
 	while (part != NULL) {
 		if (part->parent != NULL)
-			t_string_append_c(str, '(');
+			str_append_c(str, '(');
 
 		if (part->flags & MESSAGE_PART_FLAG_MULTIPART)
 			part_write_body_multipart(part, str, extended);
@@ -410,7 +408,7 @@
 			part_write_body(part, str, extended);
 
 		if (part->parent != NULL)
-			t_string_append_c(str, ')');
+			str_append_c(str, ')');
 
 		part = part->next;
 	}
@@ -418,11 +416,11 @@
 
 static const char *part_get_bodystructure(MessagePart *part, int extended)
 {
-	TempString *str;
+	String *str;
 
-	str = t_string_new(2048);
+	str = t_str_new(2048);
 	part_write_bodystructure(part, str, extended);
-	return str->str;
+	return str_c(str);
 }
 
 const char *imap_part_get_bodystructure(Pool pool, MessagePart **part,
@@ -440,22 +438,22 @@
 	return part_get_bodystructure(*part, extended);
 }
 
-static int imap_write_list(ImapArg *args, TempString *str)
+static int imap_write_list(ImapArg *args, String *str)
 {
 	/* don't do any typechecking, just write it out */
-	t_string_append_c(str, '(');
+	str_append_c(str, '(');
 	while (args->type != IMAP_ARG_EOL) {
 		switch (args->type) {
 		case IMAP_ARG_NIL:
-			t_string_append(str, "NIL");
+			str_append(str, "NIL");
 			break;
 		case IMAP_ARG_ATOM:
-			t_string_append(str, args->data.str);
+			str_append(str, args->data.str);
 			break;
 		case IMAP_ARG_STRING:
-			t_string_append_c(str, '"');
-			t_string_append(str, args->data.str);
-			t_string_append_c(str, '"');
+			str_append_c(str, '"');
+			str_append(str, args->data.str);
+			str_append_c(str, '"');
 			break;
 		case IMAP_ARG_LIST:
 			if (!imap_write_list(args->data.list->args, str))
@@ -467,23 +465,23 @@
 		args++;
 
 		if (args->type != IMAP_ARG_EOL)
-			t_string_append_c(str, ' ');
+			str_append_c(str, ' ');
 	}
-	t_string_append_c(str, ')');
+	str_append_c(str, ')');
 	return TRUE;
 }
 
-static int imap_parse_bodystructure_args(ImapArg *args, TempString *str)
+static int imap_parse_bodystructure_args(ImapArg *args, String *str)
 {
 	ImapArg *subargs;
 	int i, multipart, text, message_rfc822;
 
 	multipart = FALSE;
 	while (args->type == IMAP_ARG_LIST) {
-		t_string_append_c(str, '(');
+		str_append_c(str, '(');
 		if (!imap_parse_bodystructure_args(args->data.list->args, str))
 			return FALSE;
-		t_string_append_c(str, ')');
+		str_append_c(str, ')');
 
 		multipart = TRUE;
 		args++;
@@ -494,7 +492,7 @@
 		if (args->type != IMAP_ARG_STRING)
 			return FALSE;
 
-		t_string_printfa(str, " \"%s\"", args->data.str);
+		str_printfa(str, " \"%s\"", args->data.str);
 		return TRUE;
 	}
 
@@ -506,31 +504,29 @@
 	message_rfc822 = strcasecmp(args[0].data.str, "message") == 0 &&
 		strcasecmp(args[1].data.str, "rfc822") == 0;
 
-	t_string_printfa(str, "\"%s\" \"%s\"",
-			 args[0].data.str, args[1].data.str);
+	str_printfa(str, "\"%s\" \"%s\"", args[0].data.str, args[1].data.str);
 	args += 2;
 
 	/* ("content type param key" "value" ...) | NIL */
 	if (args->type == IMAP_ARG_LIST) {
-		t_string_append(str, " (");
+		str_append(str, " (");
                 subargs = args->data.list->args;
 		for (; subargs->type != IMAP_ARG_EOL; ) {
 			if (subargs[0].type != IMAP_ARG_STRING ||
 			    subargs[1].type != IMAP_ARG_STRING)
 				return FALSE;
 
-			t_string_printfa(str, "\"%s\" \"%s\"",
-					 subargs[0].data.str,
-					 subargs[1].data.str);
+			str_printfa(str, "\"%s\" \"%s\"",
+				    subargs[0].data.str, subargs[1].data.str);
 
 			subargs += 2;
 			if (subargs->type == IMAP_ARG_EOL)
 				break;
-			t_string_append_c(str, ' ');
+			str_append_c(str, ' ');
 		}
-		t_string_append(str, ")");
+		str_append(str, ")");
 	} else if (args->type == IMAP_ARG_NIL) {
-		t_string_append(str, " NIL");
+		str_append(str, " NIL");
 	} else {
 		return FALSE;
 	}
@@ -539,12 +535,12 @@
 	/* "content id" "content description" "transfer encoding" size */
 	for (i = 0; i < 4; i++, args++) {
 		if (args->type == IMAP_ARG_NIL) {
-			t_string_append(str, " NIL");
+			str_append(str, " NIL");
 		} else if (args->type == IMAP_ARG_ATOM) {
-			t_string_append_c(str, ' ');
-			t_string_append(str, args->data.str);
+			str_append_c(str, ' ');
+			str_append(str, args->data.str);
 		} else if (args->type == IMAP_ARG_STRING) {
-			t_string_printfa(str, " \"%s\"", args->data.str);
+			str_printfa(str, " \"%s\"", args->data.str);
 		} else {
 			return FALSE;
 		}
@@ -555,8 +551,8 @@
 		if (args->type != IMAP_ARG_ATOM)
 			return FALSE;
 
-		t_string_append_c(str, ' ');
-		t_string_append(str, args->data.str);
+		str_append_c(str, ' ');
+		str_append(str, args->data.str);
 	} else if (message_rfc822) {
 		/* message/rfc822 - envelope + bodystructure + text lines */
 		if (args[0].type != IMAP_ARG_LIST ||
@@ -564,19 +560,19 @@
 		    args[2].type != IMAP_ARG_ATOM)
 			return FALSE;
 
-		t_string_append_c(str, ' ');
+		str_append_c(str, ' ');
 
 		if (!imap_write_list(args[0].data.list->args, str))
 			return FALSE;
 
-		t_string_append_c(str, ' ');
+		str_append_c(str, ' ');
 
 		if (!imap_parse_bodystructure_args(args[1].data.list->args,
 						   str))
 			return FALSE;
 
-		t_string_append_c(str, ' ');
-		t_string_append(str, args[2].data.str);
+		str_append_c(str, ' ');
+		str_append(str, args[2].data.str);
 	}
 
 	return TRUE;
@@ -587,13 +583,13 @@
 	IStream *input;
 	ImapParser *parser;
 	ImapArg *args;
-	TempString *str;
+	String *str;
 	const char *value;
 	size_t len;
 	int ret;
 
 	len = strlen(bodystructure);
-	str = t_string_new(len);
+	str = t_str_new(len);
 
 	input = i_stream_create_from_data(data_stack_pool, bodystructure, len);
 	(void)i_stream_read(input);
@@ -605,7 +601,7 @@
 	if (ret <= 0 || !imap_parse_bodystructure_args(args, str))
 		value = NULL;
 	else
-		value = str->str;
+		value = str_c(str);
 
 	if (value == NULL)
 		i_error("Error parsing IMAP bodystructure: %s", bodystructure);
--- a/src/lib-imap/imap-envelope.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-imap/imap-envelope.c	Sun Dec 22 00:02:57 2002 +0200
@@ -2,7 +2,7 @@
 
 #include "lib.h"
 #include "istream.h"
-#include "temp-string.h"
+#include "str.h"
 #include "rfc822-address.h"
 #include "imap-parser.h"
 #include "imap-envelope.h"
@@ -61,66 +61,66 @@
 	t_pop();
 }
 
-static void imap_write_address(TempString *str, Rfc822Address *addr)
+static void imap_write_address(String *str, Rfc822Address *addr)
 {
 	if (addr == NULL) {
-		t_string_append(str, "NIL");
+		str_append(str, "NIL");
 		return;
 	}
 
-	t_string_append_c(str, '(');
+	str_append_c(str, '(');
 	while (addr != NULL) {
-		t_string_append_c(str, '(');
-		t_string_append(str, imap_quote_str_nil(addr->name));
-		t_string_append_c(str, ' ');
-		t_string_append(str, imap_quote_str_nil(addr->route));
-		t_string_append_c(str, ' ');
-		t_string_append(str, imap_quote_str_nil(addr->mailbox));
-		t_string_append_c(str, ' ');
-		t_string_append(str, imap_quote_str_nil(addr->domain));
-		t_string_append_c(str, ')');
+		str_append_c(str, '(');
+		str_append(str, imap_quote_str_nil(addr->name));
+		str_append_c(str, ' ');
+		str_append(str, imap_quote_str_nil(addr->route));
+		str_append_c(str, ' ');
+		str_append(str, imap_quote_str_nil(addr->mailbox));
+		str_append_c(str, ' ');
+		str_append(str, imap_quote_str_nil(addr->domain));
+		str_append_c(str, ')');
 
 		addr = addr->next;
 	}
-	t_string_append_c(str, ')');
+	str_append_c(str, ')');
 }
 
 void imap_envelope_write_part_data(MessagePartEnvelopeData *data,
-				   TempString *str)
+				   String *str)
 {
-	t_string_append(str, NVL(data->date, "NIL"));
-	t_string_append_c(str, ' ');
-	t_string_append(str, NVL(data->subject, "NIL"));
+	str_append(str, NVL(data->date, "NIL"));
+	str_append_c(str, ' ');
+	str_append(str, NVL(data->subject, "NIL"));
 
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	imap_write_address(str, data->from);
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	imap_write_address(str, NVL(data->sender, data->from));
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	imap_write_address(str, NVL(data->reply_to, data->from));
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	imap_write_address(str, data->to);
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	imap_write_address(str, data->cc);
-	t_string_append_c(str, ' ');
+	str_append_c(str, ' ');
 	imap_write_address(str, data->bcc);
 
-	t_string_append_c(str, ' ');
-	t_string_append(str, NVL(data->in_reply_to, "NIL"));
-	t_string_append_c(str, ' ');
-	t_string_append(str, NVL(data->message_id, "NIL"));
+	str_append_c(str, ' ');
+	str_append(str, NVL(data->in_reply_to, "NIL"));
+	str_append_c(str, ' ');
+	str_append(str, NVL(data->message_id, "NIL"));
 }
 
 const char *imap_envelope_get_part_data(MessagePartEnvelopeData *data)
 {
-	TempString *str;
+	String *str;
 
-	str = t_string_new(2048);
+	str = t_str_new(2048);
         imap_envelope_write_part_data(data, str);
-	return str->str;
+	return str_c(str);
 }
 
-static int imap_address_arg_append(ImapArg *arg, TempString *str, int *in_group)
+static int imap_address_arg_append(ImapArg *arg, String *str, int *in_group)
 {
 	ImapArgList *list;
 	const char *args[4];
@@ -143,14 +143,14 @@
 			return FALSE;
 	}
 
-	if (str->len > 0)
-		t_string_append(str, ", ");
+	if (str_len(str) > 0)
+		str_append(str, ", ");
 
 	if (*in_group) {
 		if (args[0] == NULL && args[1] == NULL &&
 		    args[2] == NULL && args[3] == NULL) {
 			/* end of group */
-			t_string_append_c(str, ';');
+			str_append_c(str, ';');
 			*in_group = FALSE;
 			return TRUE;
 		}
@@ -158,8 +158,8 @@
 		if (args[0] == NULL && args[1] == NULL &&
 		    args[2] != NULL && args[3] == NULL) {
 			/* beginning of group */
-			t_string_append(str, args[2]);
-			t_string_append(str, ": ");
+			str_append(str, args[2]);
+			str_append(str, ": ");
 			*in_group = TRUE;
 			return TRUE;
 		}
@@ -167,30 +167,30 @@
 
         /* name <@route:mailbox@domain> */
 	if (args[0] != NULL) {
-		t_string_append(str, args[0]);
-		t_string_append_c(str, ' ');
+		str_append(str, args[0]);
+		str_append_c(str, ' ');
 	}
 
-	t_string_append_c(str, '<');
+	str_append_c(str, '<');
 	if (args[1] != NULL) {
-		t_string_append_c(str, '@');
-		t_string_append(str, args[1]);
-		t_string_append_c(str, ':');
+		str_append_c(str, '@');
+		str_append(str, args[1]);
+		str_append_c(str, ':');
 	}
 	if (args[2] != NULL)
-		t_string_append(str, args[2]);
+		str_append(str, args[2]);
 	if (args[3] != NULL) {
-		t_string_append_c(str, '@');
-		t_string_append(str, args[3]);
+		str_append_c(str, '@');
+		str_append(str, args[3]);
 	}
-	t_string_append_c(str, '>');
+	str_append_c(str, '>');
 	return TRUE;
 }
 
 static const char *imap_envelope_parse_address(ImapArg *arg)
 {
 	ImapArgList *list;
-	TempString *str;
+	String *str;
 	size_t i;
 	int in_group;
 
@@ -198,7 +198,7 @@
 		return NULL;
 
 	in_group = FALSE;
-	str = t_string_new(128);
+	str = t_str_new(128);
 
         list = arg->data.list;
 	for (i = 0; i < list->size; i++) {
@@ -206,7 +206,7 @@
 			return NULL;
 	}
 
-	return str->str;
+	return str_c(str);
 }
 
 static const char *imap_envelope_parse_first_mailbox(ImapArg *arg)
--- a/src/lib-imap/imap-envelope.h	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-imap/imap-envelope.h	Sun Dec 22 00:02:57 2002 +0200
@@ -31,7 +31,7 @@
 
 /* Write envelope to given string */
 void imap_envelope_write_part_data(MessagePartEnvelopeData *data,
-				   TempString *str);
+				   String *str);
 /* Return envelope. */
 const char *imap_envelope_get_part_data(MessagePartEnvelopeData *data);
 
--- a/src/lib-imap/imap-message-cache.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-imap/imap-message-cache.c	Sun Dec 22 00:02:57 2002 +0200
@@ -2,7 +2,6 @@
 
 #include "lib.h"
 #include "istream.h"
-#include "temp-string.h"
 #include "mmap-util.h"
 #include "message-parser.h"
 #include "message-part-serialize.h"
--- a/src/lib-imap/imap-quote.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-imap/imap-quote.c	Sun Dec 22 00:02:57 2002 +0200
@@ -1,7 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
-#include "temp-string.h"
+#include "str.h"
 #include "imap-quote.h"
 
 #define IS_BREAK_CHAR(c) \
@@ -78,7 +78,7 @@
 	return i;
 }
 
-static void append_quoted_qp(TempString *str, const char *value, size_t len)
+static void append_quoted_qp(String *str, const char *value, size_t len)
 {
 	size_t i;
 	unsigned char c;
@@ -89,44 +89,44 @@
 
 	for (i = 0; i < len; i++) {
 		if (value[i] == ' ')
-			t_string_append_c(str, '_');
+			str_append_c(str, '_');
 		else if ((value[i] >= 'A' && value[i] <= 'Z') ||
 			 (value[i] >= 'a' && value[i] <= 'z') ||
 			 (value[i] >= '0' && value[i] <= '9')) {
-			t_string_append_c(str, value[i]);
+			str_append_c(str, value[i]);
 		} else {
-			t_string_append_c(str, '=');
+			str_append_c(str, '=');
 			c = (unsigned char)value[i] >> 4;
-			t_string_append_c(str, c < 10 ? (c+'0') : (c-10+'A'));
+			str_append_c(str, c < 10 ? (c+'0') : (c-10+'A'));
 			c = (unsigned char)value[i] & 0x0f;
-			t_string_append_c(str, c < 10 ? (c+'0') : (c-10+'A'));
+			str_append_c(str, c < 10 ? (c+'0') : (c-10+'A'));
 		}
 	}
 }
 
-static void append_quoted(TempString *str, const char *value, size_t len)
+static void append_quoted(String *str, const char *value, size_t len)
 {
 	size_t i;
 
 	for (i = 0; i < len; i++) {
 		if (value[i] == '\\' || value[i] == '"')
-			t_string_append_c(str, '\\');
-		t_string_append_c(str, value[i]);
+			str_append_c(str, '\\');
+		str_append_c(str, value[i]);
 	}
 }
 
 /* does two things: 1) escape '\' and '"' characters, 2) 8bit text -> QP */
-static TempString *get_quoted_str(const char *value, size_t value_len)
+static String *get_quoted_str(const char *value, size_t value_len)
 {
-	TempString *str;
+	String *str;
 	size_t token_len;
 	int qp, need_qp, quoted;
 
-	str = t_string_new(value_len * 2);
+	str = t_str_new(value_len * 2);
 	qp = FALSE;
 	quoted = FALSE;
 
-	t_string_append_c(str, '"');
+	str_append_c(str, '"');
 	while (value_len > 0) {
 		token_len = next_token(value, value_len, &need_qp, &quoted, qp);
 		i_assert(token_len > 0 && token_len <= value_len);
@@ -140,10 +140,10 @@
 		}
 
 		if (need_qp && !qp) {
-			t_string_append(str, "=?x-unknown?Q?");
+			str_append(str, "=?x-unknown?Q?");
 			qp = TRUE;
 		} else if (!need_qp && qp) {
-			t_string_append(str, "?=");
+			str_append(str, "?=");
 			qp = FALSE;
 		}
 
@@ -156,8 +156,8 @@
 		value_len -= token_len;
 	}
 
-	if (qp) t_string_append(str, "?=");
-	t_string_append_c(str, '"');
+	if (qp) str_append(str, "?=");
+	str_append_c(str, '"');
 
 	return str;
 }
@@ -165,13 +165,13 @@
 const char *imap_quote_str_nil(const char *value)
 {
 	return value == NULL ? "NIL" :
-		get_quoted_str(value, strlen(value))->str;
+		str_c(get_quoted_str(value, strlen(value)));
 }
 
 char *imap_quote_value(Pool pool, const char *value, size_t value_len)
 {
-	TempString *str;
+	String *str;
 
 	str = get_quoted_str(value, value_len);
-	return p_strndup(pool, str->str, str->len);
+	return p_strndup(pool, str_c(str), str_len(str));
 }
--- a/src/lib-imap/imap-util.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-imap/imap-util.c	Sun Dec 22 00:02:57 2002 +0200
@@ -1,13 +1,13 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
-#include "temp-string.h"
+#include "str.h"
 #include "imap-util.h"
 
 const char *imap_write_flags(MailFlags flags, const char *custom_flags[],
 			     unsigned int custom_flags_count)
 {
-	TempString *str;
+	String *str;
 	const char *sysflags, *name;
 	unsigned int i;
 
@@ -31,21 +31,21 @@
 		return sysflags;
 
 	/* we have custom flags too */
-	str = t_string_new(256);
-	t_string_append(str, sysflags);
+	str = t_str_new(256);
+	str_append(str, sysflags);
 
 	for (i = 0; i < custom_flags_count; i++) {
 		if (flags & (1 << (i + MAIL_CUSTOM_FLAG_1_BIT))) {
 			name = custom_flags[i];
 			if (name != NULL && *name != '\0') {
-				if (str->len > 0)
-					t_string_append_c(str, ' ');
-				t_string_append(str, name);
+				if (str_len(str) > 0)
+					str_append_c(str, ' ');
+				str_append(str, name);
 			}
 		}
 	}
 
-	return str->str;
+	return str_c(str);
 }
 
 const char *imap_escape(const char *str)
--- a/src/lib-index/maildir/maildir-index.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-index/maildir/maildir-index.c	Sun Dec 22 00:02:57 2002 +0200
@@ -1,7 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
-#include "temp-string.h"
+#include "str.h"
 #include "maildir-index.h"
 #include "mail-index-data.h"
 #include "mail-index-util.h"
@@ -56,7 +56,7 @@
 
 const char *maildir_filename_set_flags(const char *fname, MailFlags flags)
 {
-	TempString *flags_str;
+	String *flags_str;
 	const char *info, *oldflags;
 	int i, nextflag;
 
@@ -74,9 +74,9 @@
 
 	/* insert the new flags between old flags. flags must be sorted by
 	   their ASCII code. unknown flags are kept. */
-	flags_str = t_string_new(256);
-	t_string_append(flags_str, fname);
-	t_string_append(flags_str, ":2,");
+	flags_str = t_str_new(256);
+	str_append(flags_str, fname);
+	str_append(flags_str, ":2,");
 	for (;;) {
 		/* skip all known flags */
 		while (*oldflags == 'D' || *oldflags == 'F' ||
@@ -89,30 +89,30 @@
 			(unsigned char) *oldflags;
 
 		if ((flags & MAIL_DRAFT) && nextflag > 'D') {
-			t_string_append_c(flags_str, 'D');
+			str_append_c(flags_str, 'D');
 			flags &= ~MAIL_DRAFT;
 		}
 		if ((flags & MAIL_FLAGGED) && nextflag > 'F') {
-			t_string_append_c(flags_str, 'F');
+			str_append_c(flags_str, 'F');
 			flags &= ~MAIL_FLAGGED;
 		}
 		if ((flags & MAIL_ANSWERED) && nextflag > 'R') {
-			t_string_append_c(flags_str, 'R');
+			str_append_c(flags_str, 'R');
 			flags &= ~MAIL_ANSWERED;
 		}
 		if ((flags & MAIL_SEEN) && nextflag > 'S') {
-			t_string_append_c(flags_str, 'S');
+			str_append_c(flags_str, 'S');
 			flags &= ~MAIL_SEEN;
 		}
 		if ((flags & MAIL_DELETED) && nextflag > 'T') {
-			t_string_append_c(flags_str, 'T');
+			str_append_c(flags_str, 'T');
 			flags &= ~MAIL_DELETED;
 		}
 
 		if ((flags & MAIL_CUSTOM_FLAGS_MASK) && nextflag > 'a') {
 			for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
 				if (flags & (1 << (i + MAIL_CUSTOM_FLAG_1_BIT)))
-					t_string_append_c(flags_str, 'a' + i);
+					str_append_c(flags_str, 'a' + i);
 			}
 			flags &= ~MAIL_CUSTOM_FLAGS_MASK;
 		}
@@ -120,17 +120,17 @@
 		if (*oldflags == '\0' || *oldflags == ',')
 			break;
 
-		t_string_append_c(flags_str, *oldflags);
+		str_append_c(flags_str, *oldflags);
 		oldflags++;
 	}
 
 	if (*oldflags == ',') {
 		/* another flagset, we don't know about these, just keep them */
 		while (*oldflags != '\0')
-			t_string_append_c(flags_str, *oldflags++);
+			str_append_c(flags_str, *oldflags++);
 	}
 
-	return flags_str->str;
+	return str_c(flags_str);
 }
 
 MailIndex *maildir_index_alloc(const char *dir, const char *maildir)
--- a/src/lib-index/mbox/mbox-from.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-index/mbox/mbox-from.c	Sun Dec 22 00:02:57 2002 +0200
@@ -1,7 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
-#include "temp-string.h"
+#include "str.h"
 #include "mbox-index.h"
 
 #include <time.h>
@@ -94,54 +94,54 @@
 
 const char *mbox_from_create(const char *sender, time_t time)
 {
-	TempString *str;
+	String *str;
 	struct tm *tm;
 	int year;
 
-	str = t_string_new(256);
-	t_string_append(str, "From ");
-	t_string_append(str, sender);
-	t_string_append(str, "  ");
+	str = t_str_new(256);
+	str_append(str, "From ");
+	str_append(str, sender);
+	str_append(str, "  ");
 
 	/* we could use simply asctime(), but i18n etc. may break it.
 	   Example: "Thu Nov 29 22:33:52 2001" */
 	tm = localtime(&time);
 
 	/* week day */
-	t_string_append(str, weekdays[tm->tm_wday]);
-	t_string_append_c(str, ' ');
+	str_append(str, weekdays[tm->tm_wday]);
+	str_append_c(str, ' ');
 
 	/* month */
-	t_string_append(str, months[tm->tm_mon]);
-	t_string_append_c(str, ' ');
+	str_append(str, months[tm->tm_mon]);
+	str_append_c(str, ' ');
 
 	/* day */
-	t_string_append_c(str, (tm->tm_mday / 10) + '0');
-	t_string_append_c(str, (tm->tm_mday % 10) + '0');
-	t_string_append_c(str, ' ');
+	str_append_c(str, (tm->tm_mday / 10) + '0');
+	str_append_c(str, (tm->tm_mday % 10) + '0');
+	str_append_c(str, ' ');
 
 	/* hour */
-	t_string_append_c(str, (tm->tm_hour / 10) + '0');
-	t_string_append_c(str, (tm->tm_hour % 10) + '0');
-	t_string_append_c(str, ':');
+	str_append_c(str, (tm->tm_hour / 10) + '0');
+	str_append_c(str, (tm->tm_hour % 10) + '0');
+	str_append_c(str, ':');
 
 	/* minute */
-	t_string_append_c(str, (tm->tm_min / 10) + '0');
-	t_string_append_c(str, (tm->tm_min % 10) + '0');
-	t_string_append_c(str, ':');
+	str_append_c(str, (tm->tm_min / 10) + '0');
+	str_append_c(str, (tm->tm_min % 10) + '0');
+	str_append_c(str, ':');
 
 	/* second */
-	t_string_append_c(str, (tm->tm_sec / 10) + '0');
-	t_string_append_c(str, (tm->tm_sec % 10) + '0');
-	t_string_append_c(str, ' ');
+	str_append_c(str, (tm->tm_sec / 10) + '0');
+	str_append_c(str, (tm->tm_sec % 10) + '0');
+	str_append_c(str, ' ');
 
 	/* year */
 	year = tm->tm_year + 1900;
-	t_string_append_c(str, (year / 1000) + '0');
-	t_string_append_c(str, ((year / 100) % 10) + '0');
-	t_string_append_c(str, ((year / 10) % 10) + '0');
-	t_string_append_c(str, (year % 10) + '0');
+	str_append_c(str, (year / 1000) + '0');
+	str_append_c(str, ((year / 100) % 10) + '0');
+	str_append_c(str, ((year / 10) % 10) + '0');
+	str_append_c(str, (year % 10) + '0');
 
-	t_string_append_c(str, '\n');
-	return str->str;
+	str_append_c(str, '\n');
+	return str_c(str);
 }
--- a/src/lib-index/mbox/mbox-rewrite.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-index/mbox/mbox-rewrite.c	Sun Dec 22 00:02:57 2002 +0200
@@ -4,7 +4,7 @@
 #include "ioloop.h"
 #include "istream.h"
 #include "ostream.h"
-#include "temp-string.h"
+#include "str.h"
 #include "write-full.h"
 #include "mbox-index.h"
 #include "mbox-lock.h"
@@ -219,25 +219,25 @@
 static void update_stripped_custom_flags(const char *value, size_t len,
 					 int index, void *context)
 {
-	TempString *str = context;
+	String *str = context;
 
 	if (index < 0) {
 		/* not found, keep it */
-		if (str->len != 0)
-			t_string_append_c(str, ' ');
-		t_string_append_n(str, value, len);
+		if (str_len(str) != 0)
+			str_append_c(str, ' ');
+		str_append_n(str, value, len);
 	}
 }
 
 static const char *strip_custom_flags(const char *value, size_t len,
 				      MboxRewriteContext *ctx)
 {
-	TempString *str;
+	String *str;
 
-	str = t_string_new(len+1);
+	str = t_str_new(len+1);
 	mbox_keywords_parse(value, len, ctx->custom_flags,
 			    update_stripped_custom_flags, str);
-	return str->len == 0 ? NULL : str->str;
+	return str_len(str) == 0 ? NULL : str_c(str);
 }
 
 static void header_func(MessagePart *part __attr_unused__,
--- a/src/lib-mail/rfc822-address.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-mail/rfc822-address.c	Sun Dec 22 00:02:57 2002 +0200
@@ -1,7 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
-#include "temp-string.h"
+#include "str.h"
 #include "rfc822-tokenize.h"
 #include "rfc822-address.h"
 
@@ -18,8 +18,9 @@
 }
 
 static int read_until(const Rfc822Token *tokens, const char *stop_tokens,
-		      TempString *comment)
+		      String *comment)
 {
+	char *c_str;
 	int i, pos;
 
 	/* find the stop token */
@@ -29,15 +30,15 @@
 
 		if (tokens[i].token == '(' && comment != NULL) {
 			/* save comment */
-			if (comment->len > 0)
-				t_string_append_c(comment, ' ');
-			pos = comment->len;
+			if (str_len(comment) > 0)
+				str_append_c(comment, ' ');
+			pos = str_len(comment);
 
-			t_string_append_n(comment, tokens[i].ptr,
-					  tokens[i].len);
+			str_append_n(comment, tokens[i].ptr, tokens[i].len);
+			c_str = str_c_modifyable(comment);
 
-			str_remove_escapes(comment->str + pos);
-			comment->len = strlen(comment->str);
+			str_remove_escapes(c_str + pos);
+			str_truncate(comment, strlen(c_str));
 		}
 	}
 
@@ -45,7 +46,7 @@
 }
 
 static void read_until_get(const Rfc822Token **tokens, const char *stop_tokens,
-			   TempString *phrase, TempString *comment)
+			   String *phrase, String *comment)
 {
 	const char *value;
 	int count;
@@ -53,7 +54,7 @@
 	count = read_until(*tokens, stop_tokens, comment);
 	if (count > 0) {
 		value = rfc822_tokens_get_value(*tokens, count);
-		t_string_append(phrase, value);
+		str_append(phrase, value);
 
 		*tokens += count;
 	}
@@ -62,7 +63,7 @@
 Rfc822Address *rfc822_address_parse(Pool pool, const char *str)
 {
 	Rfc822Address *first_addr, **next_addr, *addr;
-	TempString *mailbox, *domain, *route, *name, *comment, *next_phrase;
+	String *mailbox, *domain, *route, *name, *comment, *next_phrase;
 	const Rfc822Token *tokens;
 	const char *list, *value;
 	int ingroup, stop, count;
@@ -83,11 +84,11 @@
 	tokens = rfc822_tokenize(str, NULL, NULL, NULL);
 
 	t_push();
-	mailbox = t_string_new(128);
-	domain = t_string_new(128);
-	route = t_string_new(128);
-	name = t_string_new(128);
-	comment = t_string_new(128);
+	mailbox = t_str_new(128);
+	domain = t_str_new(128);
+	route = t_str_new(128);
+	name = t_str_new(128);
+	comment = t_str_new(128);
 
 	ingroup = FALSE;
 	list = ",@<:";
@@ -97,14 +98,14 @@
 		count = read_until(tokens, list, comment);
 		if (count > 0) {
 			if ((tokens[count].token == '<' ||
-			     next_phrase == name) && next_phrase->len > 0) {
+			     next_phrase == name) && str_len(next_phrase) > 0) {
 				/* continuing previously started name,
 				   separate it from us with space */
-				t_string_append_c(next_phrase, ' ');
+				str_append_c(next_phrase, ' ');
 			}
 
 			value = rfc822_tokens_get_value(tokens, count);
-			t_string_append(next_phrase, value);
+			str_append(next_phrase, value);
 			tokens += count;
 		}
 
@@ -113,17 +114,17 @@
 		case ',':
 		case ';':
 			/* end of address */
-			if (mailbox->len > 0 || domain->len > 0 ||
-			    route->len > 0 || name->len > 0) {
+			if (str_len(mailbox) > 0 || str_len(domain) > 0 ||
+			    str_len(route) > 0 || str_len(name) > 0) {
 				addr = new_address(pool, &next_addr);
-				addr->mailbox = p_strdup(pool, mailbox->str);
-				addr->domain = domain->len == 0 ? NULL :
-					p_strdup(pool, domain->str);
-				addr->route = route->len == 0 ? NULL :
-					p_strdup(pool, route->str);
+				addr->mailbox = p_strdup(pool, str_c(mailbox));
+				addr->domain = str_len(domain) == 0 ? NULL :
+					p_strdup(pool, str_c(domain));
+				addr->route = str_len(route) == 0 ? NULL :
+					p_strdup(pool, str_c(route));
 				addr->name = next_phrase == name ?
-					p_strdup(pool, name->str) :
-					p_strdup(pool, comment->str);
+					p_strdup(pool, str_c(name)) :
+					p_strdup(pool, str_c(comment));
 			}
 
 			if (ingroup && tokens->token == ';') {
@@ -139,11 +140,11 @@
 
 			list = ingroup ? ",@<;" :  ",@<:";
 
-			t_string_truncate(mailbox, 0);
-			t_string_truncate(domain, 0);
-			t_string_truncate(route, 0);
-			t_string_truncate(name, 0);
-			t_string_truncate(comment, 0);
+			str_truncate(mailbox, 0);
+			str_truncate(domain, 0);
+			str_truncate(route, 0);
+			str_truncate(name, 0);
+			str_truncate(comment, 0);
 
 			tokens++;
 			next_phrase = mailbox;
@@ -160,17 +161,17 @@
 
 			/* mailbox/domain name so far has actually
 			   been the real name */
-			t_string_append(name, mailbox->str);
-			if (domain->len > 0) {
-                                t_string_append_c(name, '@');
-				t_string_append(name, domain->str);
+			str_append_str(name, mailbox);
+			if (str_len(domain) > 0) {
+                                str_append_c(name, '@');
+				str_append_str(name, domain);
 			}
 
-			t_string_truncate(mailbox, 0);
-			t_string_truncate(domain, 0);
+			str_truncate(mailbox, 0);
+			str_truncate(domain, 0);
 
 			read_until_get(&tokens, "@>", mailbox, NULL);
-			if (tokens->token == '@' && mailbox->len == 0) {
+			if (tokens->token == '@' && str_len(mailbox) == 0) {
 				/* route is given */
 				tokens++;
 				read_until_get(&tokens, ":>", route, NULL);
@@ -196,9 +197,9 @@
 		case ':':
 			/* beginning of group */
 			addr = new_address(pool, &next_addr);
-			addr->name = p_strdup(pool, mailbox->str);
+			addr->name = p_strdup(pool, str_c(mailbox));
 
-			t_string_truncate(mailbox, 0);
+			str_truncate(mailbox, 0);
 			tokens++;
 
 			ingroup = TRUE;
--- a/src/lib-storage/index/index-fetch-section.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-storage/index/index-fetch-section.c	Sun Dec 22 00:02:57 2002 +0200
@@ -1,7 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
-#include "temp-string.h"
+#include "str.h"
 #include "istream.h"
 #include "ostream.h"
 #include "rfc822-tokenize.h"
@@ -138,7 +138,7 @@
 }
 
 typedef struct {
-	TempString *dest;
+	String *dest;
 	OStream *output;
 	uoff_t dest_size;
 
@@ -167,7 +167,7 @@
 	}
 
 	if (ctx->dest != NULL)
-		t_string_append_n(ctx->dest, str, size);
+		str_append_n(ctx->dest, str, size);
 	ctx->dest_size += size;
 
 	if (ctx->output != NULL) {
@@ -241,7 +241,7 @@
 	message_parse_header(NULL, input, NULL, fetch_header_field, ctx);
 
 	i_assert(ctx->dest_size <= ctx->max_size);
-	i_assert(ctx->dest == NULL || ctx->dest->len == ctx->dest_size);
+	i_assert(ctx->dest == NULL || str_len(ctx->dest) == ctx->dest_size);
 	return TRUE;
 }
 
@@ -288,8 +288,8 @@
 
 		i_assert(ctx.dest_size <= size->virtual_size);
 	} else {
-		ctx.dest = t_string_new(size->virtual_size < 4096 ?
-					size->virtual_size : 4096);
+		ctx.dest = t_str_new(size->virtual_size < 4096 ?
+				     size->virtual_size : 4096);
 		if (!fetch_header_fields(input, section, &ctx))
 			failed = TRUE;
 	}
@@ -315,8 +315,8 @@
 
 			i_assert(first_size == ctx.dest_size);
 		} else {
-			if (o_stream_send(output, ctx.dest->str,
-					  ctx.dest->len) < 0)
+			if (o_stream_send(output, str_c(ctx.dest),
+					  str_len(ctx.dest)) < 0)
 				failed = TRUE;
 		}
 	}
--- a/src/lib-storage/index/index-fetch.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-storage/index/index-fetch.c	Sun Dec 22 00:02:57 2002 +0200
@@ -2,7 +2,7 @@
 
 #include "lib.h"
 #include "ostream.h"
-#include "temp-string.h"
+#include "str.h"
 #include "mail-custom-flags.h"
 #include "index-storage.h"
 #include "index-fetch.h"
@@ -20,8 +20,8 @@
 
 	date = imap_msgcache_get_internal_date(ctx->cache);
 	if (date != (time_t)-1) {
-		t_string_printfa(ctx->str, "INTERNALDATE \"%s\" ",
-				 imap_to_datetime(date));
+		str_printfa(ctx->str, "INTERNALDATE \"%s\" ",
+			    imap_to_datetime(date));
 		return TRUE;
 	} else {
 		mail_storage_set_critical(ctx->storage,
@@ -37,7 +37,7 @@
 
 	body = imap_msgcache_get(ctx->cache, IMAP_CACHE_BODY);
 	if (body != NULL) {
-		t_string_printfa(ctx->str, "BODY (%s) ", body);
+		str_printfa(ctx->str, "BODY (%s) ", body);
 		return TRUE;
 	} else {
 		mail_storage_set_critical(ctx->storage,
@@ -53,8 +53,7 @@
 
 	bodystructure = imap_msgcache_get(ctx->cache, IMAP_CACHE_BODYSTRUCTURE);
 	if (bodystructure != NULL) {
-		t_string_printfa(ctx->str, "BODYSTRUCTURE (%s) ",
-				 bodystructure);
+		str_printfa(ctx->str, "BODYSTRUCTURE (%s) ", bodystructure);
 		return TRUE;
 	} else {
 		mail_storage_set_critical(ctx->storage,
@@ -70,7 +69,7 @@
 
 	envelope = imap_msgcache_get(ctx->cache, IMAP_CACHE_ENVELOPE);
 	if (envelope != NULL) {
-		t_string_printfa(ctx->str, "ENVELOPE (%s) ", envelope);
+		str_printfa(ctx->str, "ENVELOPE (%s) ", envelope);
 		return TRUE;
 	} else {
 		mail_storage_set_critical(ctx->storage,
@@ -92,7 +91,7 @@
 		return FALSE;
 	}
 
-	t_string_printfa(ctx->str, "RFC822.SIZE %"PRIuUOFF_T" ", size);
+	str_printfa(ctx->str, "RFC822.SIZE %"PRIuUOFF_T" ", size);
 	return TRUE;
 }
 
@@ -106,14 +105,14 @@
 	if (ctx->update_seen)
 		flags |= MAIL_SEEN;
 
-	t_string_printfa(ctx->str, "FLAGS (%s) ",
-			 imap_write_flags(flags, ctx->custom_flags,
-					  ctx->custom_flags_count));
+	str_printfa(ctx->str, "FLAGS (%s) ",
+		    imap_write_flags(flags, ctx->custom_flags,
+				     ctx->custom_flags_count));
 }
 
 static void index_fetch_uid(MailIndexRecord *rec, FetchContext *ctx)
 {
-	t_string_printfa(ctx->str, "UID %u ", rec->uid);
+	str_printfa(ctx->str, "UID %u ", rec->uid);
 }
 
 static int index_fetch_send_rfc822(MailIndexRecord *rec, FetchContext *ctx)
@@ -244,7 +243,7 @@
 {
 	FetchContext *ctx = context;
 	MailFetchBodyData *sect;
-	unsigned int orig_len;
+	size_t len, orig_len;
 	int failed, data_written, fetch_flags;
 
 	/* first see what we need to do. this way we don't first do some
@@ -265,10 +264,10 @@
 		fetch_flags = FALSE;
 	}
 
-	ctx->str = t_string_new(2048);
+	ctx->str = t_str_new(2048);
 
-	t_string_printfa(ctx->str, "* %u FETCH (", client_seq);
-	orig_len = ctx->str->len;
+	str_printfa(ctx->str, "* %u FETCH (", client_seq);
+	orig_len = str_len(ctx->str);
 
 	failed = TRUE;
 	data_written = FALSE;
@@ -298,13 +297,14 @@
 
 		/* send the data written into temp string,
 		   not including the trailing zero */
-		ctx->first = ctx->str->len == orig_len;
-		if (ctx->str->len > 0) {
+		ctx->first = str_len(ctx->str) == orig_len;
+		len = str_len(ctx->str);
+		if (len > 0) {
 			if (!ctx->first)
-				ctx->str->len--;
+				str_truncate(ctx->str, len-1);
 
-			if (o_stream_send(ctx->output, ctx->str->str,
-					  ctx->str->len) < 0)
+			if (o_stream_send(ctx->output,
+					  str_c(ctx->str), len) < 0)
 				break;
 		}
 
--- a/src/lib-storage/index/index-fetch.h	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib-storage/index/index-fetch.h	Sun Dec 22 00:02:57 2002 +0200
@@ -12,7 +12,7 @@
 
 	MailFetchData *fetch_data;
 	OStream *output;
-	TempString *str;
+	String *str;
 	int update_seen, failed;
 	int first;
 } FetchContext;
--- a/src/lib/Makefile.am	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib/Makefile.am	Sun Dec 22 00:02:57 2002 +0200
@@ -44,7 +44,7 @@
 	safe-mkdir.c \
 	sendfile-util.c \
 	strfuncs.c \
-	temp-string.c \
+	str.c \
 	unlink-directory.c \
 	unlink-lockfiles.c \
 	utc-offset.c \
@@ -90,7 +90,7 @@
 	safe-mkdir.h \
 	sendfile-util.h \
 	strfuncs.h \
-	temp-string.h \
+	str.h \
 	unlink-directory.h \
 	unlink-lockfiles.h \
 	utc-offset.h \
--- a/src/lib/lib.h	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib/lib.h	Sun Dec 22 00:02:57 2002 +0200
@@ -25,7 +25,7 @@
 typedef struct _IStream IStream;
 typedef struct _OStream OStream;
 typedef struct _Buffer Buffer;
-typedef struct _TempString TempString;
+typedef struct _Buffer String;
 
 #include "compat.h"
 #include "macros.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/str.c	Sun Dec 22 00:02:57 2002 +0200
@@ -0,0 +1,144 @@
+/*
+    Copyright (c) 2002 Timo Sirainen
+
+    Permission is hereby granted, free of charge, to any person obtaining
+    a copy of this software and associated documentation files (the
+    "Software"), to deal in the Software without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Software, and to
+    permit persons to whom the Software is furnished to do so, subject to
+    the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/* @UNSAFE: whole file */
+
+#include "lib.h"
+#include "buffer.h"
+#include "str.h"
+
+#include <stdio.h>
+
+String *str_new(Pool pool, size_t initial_size)
+{
+	return buffer_create_dynamic(pool, initial_size, (size_t)-1);
+}
+
+String *t_str_new(size_t initial_size)
+{
+	return str_new(data_stack_pool, initial_size);
+}
+
+static int str_add_nul(String *str)
+{
+	size_t len;
+
+	len = str_len(str);
+	if (buffer_write(str, len, "", 1) != 1) {
+		/* no space - doesn't happen with our dynamically growing
+		   strings though, but make sure it's \0 terminated. */
+		if (len == 0)
+			return FALSE;
+
+		len--;
+		if (buffer_write(str, len, "", 1) != 1)
+			i_panic("BUG in str_c()");
+	}
+
+	/* remove the \0 - we don't want to keep it */
+	buffer_set_used_size(str, len);
+	return TRUE;
+}
+
+const char *str_c(String *str)
+{
+	if (!str_add_nul(str))
+		return "";
+
+	return buffer_get_data(str, NULL);
+}
+
+char *str_c_modifyable(String *str)
+{
+	if (!str_add_nul(str))
+		return NULL;
+
+	return buffer_get_modifyable_data(str, NULL);
+}
+
+size_t str_len(const String *str)
+{
+	return buffer_get_used_size(str);
+}
+
+void str_append(String *str, const char *cstr)
+{
+	buffer_append(str, cstr, strlen(cstr));
+}
+
+void str_append_n(String *str, const char *cstr, size_t max_len)
+{
+	size_t len;
+
+	len = 0;
+	while (len < max_len && cstr[len] != '\0')
+		len++;
+
+	buffer_append(str, cstr, len);
+}
+
+void str_append_c(String *str, char chr)
+{
+	buffer_append_c(str, chr);
+}
+
+void str_append_str(String *dest, const String *src)
+{
+	const char *cstr;
+	size_t len;
+
+	cstr = buffer_get_data(src, &len);
+	buffer_append(dest, cstr, len);
+}
+
+void str_printfa(String *str, const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	str_vprintfa(str, fmt, args);
+	va_end(args);
+}
+
+void str_vprintfa(String *str, const char *fmt, va_list args)
+{
+	char *buf;
+	size_t len;
+
+	len = buffer_get_used_size(str);
+
+	buf = buffer_append_space(str, printf_string_upper_bound(fmt, args));
+	len += vsprintf(buf, fmt, args);
+
+	buffer_set_used_size(str, len);
+}
+
+void str_delete(String *str, size_t pos, size_t len)
+{
+	buffer_delete(str, pos, len);
+}
+
+void str_truncate(String *str, size_t len)
+{
+	buffer_set_used_size(str, len);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/str.h	Sun Dec 22 00:02:57 2002 +0200
@@ -0,0 +1,26 @@
+#ifndef __STR_H
+#define __STR_H
+
+String *str_new(Pool pool, size_t initial_size);
+String *t_str_new(size_t initial_size);
+
+const char *str_c(String *str);
+char *str_c_modifyable(String *str);
+size_t str_len(const String *str);
+
+/* Append string/character */
+void str_append(String *str, const char *cstr);
+void str_append_n(String *str, const char *cstr, size_t max_len);
+void str_append_c(String *str, char chr);
+void str_append_str(String *dest, const String *src);
+
+/* Append printf()-like data */
+void str_printfa(String *str, const char *fmt, ...)
+	__attr_format__(2, 3);
+void str_vprintfa(String *str, const char *fmt, va_list args);
+
+/* Delete/truncate */
+void str_delete(String *str, size_t pos, size_t len);
+void str_truncate(String *str, size_t len);
+
+#endif
--- a/src/lib/strfuncs.h	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/lib/strfuncs.h	Sun Dec 22 00:02:57 2002 +0200
@@ -7,7 +7,7 @@
 #define MAX_INT_STRLEN ((sizeof(uintmax_t) * CHAR_BIT + 2) / 3 + 1)
 
 size_t printf_string_upper_bound(const char *format, va_list args);
-const char *printf_string_fix_format(const char *fmt);
+const char *printf_string_fix_format(const char *fmt) __attr_format_arg__(1);
 
 /* Returns -1 if dest wasn't large enough, 0 if not. */
 int i_snprintf(char *dest, size_t max_chars, const char *format, ...)
--- a/src/lib/temp-string.c	Sun Dec 22 00:02:20 2002 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- temp-string.c : Temporary string
-
-    Copyright (c) 2002 Timo Sirainen
-
-    Permission is hereby granted, free of charge, to any person obtaining
-    a copy of this software and associated documentation files (the
-    "Software"), to deal in the Software without restriction, including
-    without limitation the rights to use, copy, modify, merge, publish,
-    distribute, sublicense, and/or sell copies of the Software, and to
-    permit persons to whom the Software is furnished to do so, subject to
-    the following conditions:
-
-    The above copyright notice and this permission notice shall be
-    included in all copies or substantial portions of the Software.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-/* @UNSAFE: whole file */
-
-#include "lib.h"
-#include "temp-string.h"
-
-#include <stdio.h>
-
-typedef struct {
-	char *str;
-	size_t len;
-
-	size_t alloc_size;
-#ifndef DISABLE_ASSERTS
-	unsigned int data_stack_frame;
-#endif
-} RealTempString;
-
-TempString *t_string_new(size_t initial_size)
-{
-	RealTempString *rstr;
-
-	if (initial_size <= 0)
-		initial_size = 64;
-
-	rstr = t_new(RealTempString, 1);
-#ifndef DISABLE_ASSERTS
-	rstr->data_stack_frame = data_stack_frame;
-#endif
-	rstr->alloc_size = initial_size;
-	rstr->str = t_malloc(rstr->alloc_size);
-	rstr->str[0] = '\0';
-	return (TempString *) rstr;
-}
-
-static void t_string_inc(TempString *tstr, size_t size)
-{
-	RealTempString *rstr = (RealTempString *) tstr;
-	char *str;
-
-	i_assert(data_stack_frame == rstr->data_stack_frame);
-
-	size += rstr->len + 1;
-	if (size <= rstr->len || size > SSIZE_T_MAX) {
-		/* overflow */
-		i_panic("t_string_inc(): Out of memory %"PRIuSIZE_T" bytes",
-			size);
-	}
-
-	if (size > rstr->alloc_size) {
-                rstr->alloc_size = nearest_power(size);
-
-		if (!t_try_realloc(rstr->str, rstr->alloc_size)) {
-			str = t_malloc(rstr->alloc_size);
-			memcpy(str, rstr->str, rstr->len+1);
-			rstr->str = str;
-		}
-	}
-}
-
-/* Append string/character */
-void t_string_append(TempString *tstr, const char *str)
-{
-	t_string_append_n(tstr, str, SSIZE_T_MAX-1);
-}
-
-void t_string_append_n(TempString *tstr, const char *str, size_t max_len)
-{
-	size_t len;
-
-	i_assert(max_len < SSIZE_T_MAX);
-
-	len = 0;
-	while (len < max_len && str[len] != '\0')
-		len++;
-
-	t_string_inc(tstr, len);
-	memcpy(tstr->str + tstr->len, str, len);
-
-	tstr->len += len;
-	tstr->str[tstr->len] = '\0';
-}
-
-void t_string_append_c(TempString *tstr, char chr)
-{
-	t_string_inc(tstr, 1);
-	tstr->str[tstr->len++] = chr;
-	tstr->str[tstr->len] = '\0';
-}
-
-void t_string_printfa(TempString *tstr, const char *fmt, ...)
-{
-	va_list args, args2;
-
-	va_start(args, fmt);
-	VA_COPY(args2, args);
-
-	t_string_inc(tstr, printf_string_upper_bound(fmt, args));
-	tstr->len += vsprintf(tstr->str + tstr->len, fmt, args2);
-
-	va_end(args);
-}
-
-void t_string_erase(TempString *tstr, size_t pos, size_t len)
-{
-	i_assert(data_stack_frame ==
-		 ((RealTempString *) tstr)->data_stack_frame);
-	i_assert(pos < tstr->len && tstr->len - pos >= len);
-
-	memmove(tstr->str + pos + len, tstr->str + pos,
-		tstr->len - pos - len + 1);
-}
-
-void t_string_truncate(TempString *tstr, size_t len)
-{
-	i_assert(data_stack_frame ==
-		 ((RealTempString *) tstr)->data_stack_frame);
-	i_assert(len <= tstr->len);
-
-	tstr->len = len;
-	tstr->str[tstr->len] = '\0';
-}
--- a/src/lib/temp-string.h	Sun Dec 22 00:02:20 2002 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#ifndef __TEMP_STRING_H
-#define __TEMP_STRING_H
-
-/* All memory in TempString is allocated from data stack, so it MUST NOT be
-   stored permanently. */
-
-struct _TempString {
-	char *str;
-	size_t len;
-};
-
-TempString *t_string_new(size_t initial_size);
-
-/* Append string/character */
-void t_string_append(TempString *tstr, const char *str);
-void t_string_append_n(TempString *tstr, const char *str, size_t max_len);
-void t_string_append_c(TempString *tstr, char chr);
-
-/* Append printf()-like data */
-void t_string_printfa(TempString *tstr, const char *fmt, ...)
-	__attr_format__(2, 3);
-
-/* Erase/truncate */
-void t_string_erase(TempString *tstr, size_t pos, size_t len);
-void t_string_truncate(TempString *tstr, size_t len);
-
-#endif
--- a/src/login/client-authenticate.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/login/client-authenticate.c	Sun Dec 22 00:02:57 2002 +0200
@@ -7,7 +7,7 @@
 #include "istream.h"
 #include "ostream.h"
 #include "safe-memset.h"
-#include "temp-string.h"
+#include "str.h"
 #include "auth-connection.h"
 #include "client.h"
 #include "client-authenticate.h"
@@ -29,7 +29,7 @@
 
 const char *client_authenticate_get_capabilities(void)
 {
-	TempString *str;
+	String *str;
 	int i;
 
 	if (auth_methods == available_auth_methods)
@@ -38,19 +38,18 @@
 	auth_methods = available_auth_methods;
 	i_free(auth_methods_capability);
 
-	str = t_string_new(128);
+	str = t_str_new(128);
 
 	for (i = 0; i < AUTH_METHODS_COUNT; i++) {
 		if ((auth_methods & auth_method_desc[i].method) &&
 		    auth_method_desc[i].name != NULL) {
-			t_string_append_c(str, ' ');
-			t_string_append(str, "AUTH=");
-			t_string_append(str, auth_method_desc[i].name);
+			str_append_c(str, ' ');
+			str_append(str, "AUTH=");
+			str_append(str, auth_method_desc[i].name);
 		}
 	}
 
-	auth_methods_capability = str->len == 1 ? NULL :
-		i_strdup_empty(str->str);
+	auth_methods_capability = i_strdup_empty(str_c(str));
 	return auth_methods_capability;
 }
 
--- a/src/master/imap-process.c	Sun Dec 22 00:02:20 2002 +0200
+++ b/src/master/imap-process.c	Sun Dec 22 00:02:57 2002 +0200
@@ -2,7 +2,7 @@
 
 #include "common.h"
 #include "env-util.h"
-#include "temp-string.h"
+#include "str.h"
 #include "restrict-access.h"
 #include "restrict-process-size.h"
 
@@ -67,33 +67,33 @@
 static const char *expand_mail_env(const char *env, const char *user,
 				   const char *home)
 {
-	TempString *str;
+	String *str;
 	const char *p, *var;
 	unsigned int width;
 
-	str = t_string_new(256);
+	str = t_str_new(256);
 
 	/* it's either type:data or just data */
 	p = strchr(env, ':');
 	if (p != NULL) {
 		while (env != p) {
-			t_string_append_c(str, *env);
+			str_append_c(str, *env);
 			env++;
 		}
 
-		t_string_append_c(str, *env++);
+		str_append_c(str, *env++);
 	}
 
 	if (env[0] == '~' && env[1] == '/') {
 		/* expand home */
-		t_string_append(str, home);
+		str_append(str, home);
 		env++;
 	}
 
 	/* expand %vars */
 	for (; *env != '\0'; env++) {
 		if (*env != '%')
-			t_string_append_c(str, *env);
+			str_append_c(str, *env);
 		else {
 			width = 0;
 			while (env[1] >= '0' && env[1] <= '9') {
@@ -125,14 +125,14 @@
 
 			if (var != NULL) {
 				if (width == 0)
-					t_string_append(str, var);
+					str_append(str, var);
 				else
-					t_string_append_n(str, var, width);
+					str_append_n(str, var, width);
 			}
 		}
 	}
 
-	return str->str;
+	return str_c(str);
 }
 
 MasterReplyResult create_imap_process(int socket, IPADDR *ip,