void test_str_append_c(void) { str dst; str_create_from_cstr(&dst, "base_string"); str_append_c(&dst, "appended_string"); CU_ASSERT(str_size(&dst) == 26); CU_ASSERT_PTR_NOT_NULL(dst.data); CU_ASSERT_NSTRING_EQUAL(dst.data, "base_string", 11); CU_ASSERT_NSTRING_EQUAL(dst.data+11, "appended_string", 15); CU_ASSERT(dst.data[dst.len] == 0); str_free(&dst); }
static void xml_encode_id(struct solr_fts_backend_update_context *ctx, string_t *str, uint32_t uid) { struct solr_fts_backend *backend = (struct solr_fts_backend *)ctx->ctx.backend; if (uid != 0) str_printfa(str, "%u/", uid); else str_append(str, "L/"); if (backend->id_namespace != NULL) { xml_encode(str, backend->id_namespace); str_append_c(str, '/'); } str_printfa(str, "%u/", ctx->uid_validity); xml_encode(str, backend->id_username); str_append_c(str, '/'); xml_encode(str, ctx->id_box_name); }
void stats_connection_disconnect(struct stats_connection *conn, struct mail_user *user) { struct stats_user *suser = STATS_USER_CONTEXT(user); string_t *str = t_str_new(128); str_append(str, "DISCONNECT\t"); str_append(str, guid_128_to_string(suser->session_guid)); str_append_c(str, '\n'); stats_connection_send(conn, str); }
static void status_flags_append(string_t *str, enum mail_flags flags, const struct mbox_flag_type *flags_list) { int i; flags ^= MBOX_NONRECENT_KLUDGE; for (i = 0; flags_list[i].chr != 0; i++) { if ((flags & flags_list[i].flag) != 0) str_append_c(str, flags_list[i].chr); } }
void mail_search_args_to_cmdline(string_t *dest, const struct mail_search_arg *args) { const struct mail_search_arg *arg; for (arg = args; arg != NULL; arg = arg->next) { mail_search_arg_to_cmdline(dest, arg); if (arg->next != NULL) str_append_c(dest, ' '); } }
bool cmd_namespace(struct client_command_context *cmd) { struct client *client = cmd->client; string_t *str; str = t_str_new(256); str_append(str, "* NAMESPACE "); list_namespaces(client->user->namespaces, MAIL_NAMESPACE_TYPE_PRIVATE, str); str_append_c(str, ' '); list_namespaces(client->user->namespaces, MAIL_NAMESPACE_TYPE_SHARED, str); str_append_c(str, ' '); list_namespaces(client->user->namespaces, MAIL_NAMESPACE_TYPE_PUBLIC, str); client_send_line(client, str_c(str)); client_send_tagline(cmd, "OK Namespace completed."); return TRUE; }
void client_authenticate_get_capabilities(struct client *client, string_t *str) { const struct auth_mech_desc *mech; unsigned int i, count; mech = sasl_server_get_advertised_mechs(client, &count); for (i = 0; i < count; i++) { str_append_c(str, ' '); str_append(str, "AUTH="); str_append(str, mech[i].name); } }
static void lmtp_append_xtext(string_t *dest, const char *str) { unsigned int i; for (i = 0; str[i] != '\0'; i++) { if (str[i] >= 33 && str[i] <= 126 && str[i] != '+' && str[i] != '=') str_append_c(dest, str[i]); else str_printfa(dest, "+%02X", str[i]); } }
static void script_execute_finish(void) { const char *keys_str, *username, *const *keys, *value; string_t *reply = t_str_new(512); ssize_t ret; keys_str = getenv(ENV_USERDB_KEYS); if (keys_str == NULL) i_fatal(ENV_USERDB_KEYS" environment missing"); username = getenv("USER"); if (username == NULL) i_fatal("USER environment missing"); str_append(reply, username); for (keys = t_strsplit_spaces(keys_str, " "); *keys != NULL; keys++) { value = getenv(t_str_ucase(*keys)); if (value != NULL) { str_append_c(reply, '\t'); str_append_tabescaped(reply, t_strconcat(t_str_lcase(*keys), "=", value, NULL)); } } str_append_c(reply, '\n'); /* finish by sending the fd to the mail process */ ret = fd_send(SCRIPT_COMM_FD, STDOUT_FILENO, str_data(reply), str_len(reply)); if (ret == (ssize_t)str_len(reply)) { /* success */ } else { if (ret < 0) i_error("fd_send() failed: %m"); else i_error("fd_send() sent partial output"); /* exit with 0 even though we failed. non-0 exit just makes master log an unnecessary error. */ } }
static void list_namespaces(struct mail_namespace *ns, enum mail_namespace_type type, string_t *str) { string_t *mutf7_prefix = t_str_new(64); char ns_sep; bool found = FALSE; while (ns != NULL) { if (ns->type == type && (ns->flags & NAMESPACE_FLAG_HIDDEN) == 0) { if (!found) { str_append_c(str, '('); found = TRUE; } ns_sep = mail_namespace_get_sep(ns); str_append_c(str, '('); str_truncate(mutf7_prefix, 0); if (imap_utf8_to_utf7(ns->prefix, mutf7_prefix) < 0) { i_panic("LIST: Namespace prefix not UTF-8: %s", ns->prefix); } imap_append_string(str, str_c(mutf7_prefix)); str_append(str, " \""); if (ns_sep == '\\') str_append_c(str, '\\'); str_append_c(str, ns_sep); str_append(str, "\")"); } ns = ns->next; } if (found) str_append_c(str, ')'); else str_append(str, "NIL"); }
static int filter_connect(struct mail_filter_istream *mstream, const char *socket_path, const char *args) { const char **argv; string_t *str; int fd; argv = t_strsplit(args, " "); if ((fd = net_connect_unix_with_retries(socket_path, 1000)) < 0) { if (errno == EACCES) { i_error("ext-filter: %s", eacces_error_get("net_connect_unix", socket_path)); } else { i_error("ext-filter: net_connect_unix(%s) failed: %m", socket_path); } return -1; } if (mstream->istream.istream.blocking) net_set_nonblock(fd, FALSE); mstream->fd = fd; mstream->ext_in = i_stream_create_fd(fd, mstream->istream.max_buffer_size, FALSE); mstream->ext_out = o_stream_create_fd(fd, 0, FALSE); str = t_str_new(256); str_append(str, "VERSION\tscript\t3\t0\nnoreply\n"); for (; *argv != NULL; argv++) { str_append(str, *argv); str_append_c(str, '\n'); } str_append_c(str, '\n'); o_stream_send(mstream->ext_out, str_data(str), str_len(str)); return 0; }
static void proxy_write_id(struct imap_client *client, string_t *str) { i_assert(client->common.proxy_ttl > 1); str_append(str, "I ID ("); if (client->common.client_id != NULL && str_len(client->common.client_id) > 0) { str_append_str(str, client->common.client_id); str_append_c(str, ' '); } str_printfa(str, "\"x-session-id\" \"%s\" " "\"x-originating-ip\" \"%s\" " "\"x-originating-port\" \"%u\" " "\"x-connected-ip\" \"%s\" " "\"x-connected-port\" \"%u\" " "\"x-proxy-ttl\" \"%u\"", client_get_session_id(&client->common), net_ip2addr(&client->common.ip), client->common.remote_port, net_ip2addr(&client->common.local_ip), client->common.local_port, client->common.proxy_ttl - 1); /* append any forward_ variables to request */ for(const char *const *ptr = client->common.auth_passdb_args; *ptr != NULL; ptr++) { if (strncasecmp(*ptr, "forward_", 8) == 0) { const char *key = t_strconcat("x-forward-", t_strcut((*ptr)+8, '='), NULL); const char *val = i_strchr_to_next(*ptr, '='); str_append_c(str, ' '); imap_append_string(str, key); str_append_c(str, ' '); imap_append_nstring(str, val); } } str_append(str, ")\r\n"); }
static int json_parse_digits(struct json_parser *parser) { if (parser->data == parser->end) return 0; if (*parser->data < '0' || *parser->data > '9') return -1; while (parser->data != parser->end && *parser->data >= '0' && *parser->data <= '9') str_append_c(parser->value, *parser->data++); return 1; }
bool mail_search_args_to_imap(string_t *dest, const struct mail_search_arg *args, const char **error_r) { const struct mail_search_arg *arg; for (arg = args; arg != NULL; arg = arg->next) { if (!mail_search_arg_to_imap(dest, arg, error_r)) return FALSE; if (arg->next != NULL) str_append_c(dest, ' '); } return TRUE; }
void str_append_tabunescaped(string_t *dest, const void *src, size_t src_size) { const unsigned char *src_c = src; size_t start = 0, i = 0; while (i < src_size) { for (; i < src_size; i++) { if (src_c[i] == '\001') break; } str_append_n(dest, src_c + start, i-start); if (i < src_size) { i++; if (i < src_size) { switch (src_c[i]) { case '1': str_append_c(dest, '\001'); break; case 't': str_append_c(dest, '\t'); break; case 'r': str_append_c(dest, '\r'); break; case 'n': str_append_c(dest, '\n'); break; default: str_append_c(dest, src_c[i]); break; } i++; } } start = i; } }
static void cmd_acl_get_right(const struct acl_rights *rights) { string_t *str; doveadm_print(acl_rights_get_id(rights)); if (rights->global) doveadm_print("global"); else doveadm_print(""); str = t_str_new(256); if (rights->rights != NULL) str_append(str, t_strarray_join(rights->rights, " ")); if (rights->neg_rights != NULL) { if (str_len(str) > 0) str_append_c(str, ' '); str_append_c(str, '-'); str_append(str, t_strarray_join(rights->neg_rights, " -")); } doveadm_print(str_c(str)); }
void imap_refresh_proctitle(void) { #define IMAP_PROCTITLE_PREFERRED_LEN 80 struct client *client; struct client_command_context *cmd; string_t *title = t_str_new(128); if (!verbose_proctitle) return; str_append_c(title, '['); switch (imap_client_count) { case 0: str_append(title, "idling"); break; case 1: client = imap_clients; str_append(title, client->user->username); if (client->user->remote_ip != NULL) { str_append_c(title, ' '); str_append(title, net_ip2addr(client->user->remote_ip)); } for (cmd = client->command_queue; cmd != NULL; cmd = cmd->next) { if (cmd->name == NULL) continue; if (str_len(title) > IMAP_PROCTITLE_PREFERRED_LEN) break; str_append_c(title, ' '); str_append(title, cmd->name); } break; default: str_printfa(title, "%u connections", imap_client_count); break; } str_append_c(title, ']'); process_title_set(str_c(title)); }
void str_sanitize_append(string_t *dest, const char *src, size_t max_bytes) { unsigned int len, initial_pos = str_len(dest); unichar_t chr; size_t i; int ret; for (i = 0; src[i] != '\0'; ) { len = uni_utf8_char_bytes(src[i]); if (i + len > max_bytes) break; ret = uni_utf8_get_char(src+i, &chr); if (ret <= 0) { /* invalid UTF-8 */ str_append_c(dest, '?'); if (ret == 0) { /* input ended too early */ return; } i++; continue; } if ((unsigned char)src[i] < 32) str_append_c(dest, '?'); else str_append_n(dest, src+i, len); i += len; } if (src[i] != '\0') { if (max_bytes < 3) str_truncate(dest, initial_pos); else { while (str_len(dest) - initial_pos > max_bytes-3) str_sanitize_truncate_char(dest, initial_pos); } str_append(dest, "..."); } }
bool uri_data_decode(struct uri_parser *parser, const char *data, const char *until, const char **decoded_r) { const unsigned char *p = (const unsigned char *)data; const unsigned char *pend = (const unsigned char *)until; string_t *decoded; if (pend == NULL) { /* NULL means unlimited; solely rely on '\0' */ pend = (const unsigned char *)(size_t)-1; } if (p >= pend || *p == '\0') { if (decoded_r != NULL) *decoded_r = ""; return TRUE; } decoded = uri_parser_get_tmpbuf(parser, 256); while (p < pend && *p != '\0') { unsigned char ch; if (*p == '%') { p++; if (uri_parse_pct_encoded(parser, &p, NULL, &ch) <= 0) return FALSE; str_append_c(decoded, ch); } else { str_append_c(decoded, *p); p++; } } if (decoded_r != NULL) *decoded_r = t_strdup(str_c(decoded)); return TRUE; }
static void lookup_credentials_callback(enum passdb_result result, const unsigned char *credentials, size_t size, struct auth_request *request) { struct auth_worker_client *client = request->context; string_t *str; if (request->failed && result == PASSDB_RESULT_OK) result = PASSDB_RESULT_PASSWORD_MISMATCH; str = t_str_new(128); str_printfa(str, "%u\t", request->id); if (result != PASSDB_RESULT_OK && result != PASSDB_RESULT_NEXT) str_printfa(str, "FAIL\t%d", result); else { if (result == PASSDB_RESULT_NEXT) str_append(str, "NEXT\t"); else str_append(str, "OK\t"); str_append_tabescaped(str, request->user); str_append_c(str, '\t'); if (request->credentials_scheme[0] != '\0') { str_printfa(str, "{%s.b64}", request->credentials_scheme); base64_encode(credentials, size, str); } else { i_assert(size == 0); } reply_append_extra_fields(str, request); } str_append_c(str, '\n'); auth_worker_send_reply(client, request, str); auth_request_unref(&request); auth_worker_client_check_throttle(client); auth_worker_client_unref(&client); }
void str_vprintf (str_t d, const char *fmt, int append, va_list ap) { #define STR_BUFSIZE 64 char buffer[STR_BUFSIZE]; char *xbuf; int xbuf_size; int ns; va_list aq; va_copy (aq, ap); ns = vsnprintf (buffer, STR_BUFSIZE, fmt, ap); if (ns >= STR_BUFSIZE) { xbuf_size = ns+1; xbuf = malloc (xbuf_size); vsnprintf (xbuf, xbuf_size, fmt, aq); } else { xbuf = buffer; xbuf_size = 0; } va_end (aq); if (append) { str_append_c (d, xbuf, 0); if (xbuf_size > 0) free (xbuf); } else { if (xbuf_size > 0) { free (d->heap); d->heap = xbuf; d->size = xbuf_size; d->length = ns; } else { str_copy_c_substr (d, xbuf, ns); } } #undef STR_BUFSIZE }
static const char * subsfile_list_unescaped(struct subsfile_list_context *ctx, const char *line) { const char *p; str_truncate(ctx->name, 0); while ((p = strchr(line, '\t')) != NULL) { str_append_tabunescaped(ctx->name, line, p-line); str_append_c(ctx->name, mailbox_list_get_hierarchy_sep(ctx->list)); line = p+1; } str_append_tabunescaped(ctx->name, line, strlen(line)); return str_c(ctx->name); }
void test_istream_tee(void) { string_t *str; unsigned int i; str = str_new(default_pool, TEST_STR_LEN); for (i = 0; i < TEST_STR_LEN; i++) str_append_c(str, 'a' + i%26); test_istream_tee_tailing(str_c(str)); test_istream_tee_blocks(str_c(str)); str_free(&str); }
static void test_binary_to_hex(void) { static unsigned char input[] = { 0xff, 0x00, 0x01, 0xb3 }; static char *output_lcase = "ff0001b3"; static char *output_ucase = "FF0001B3"; string_t *str; test_begin("binary to hex"); test_assert(strcmp(binary_to_hex(input, sizeof(input)), output_lcase) == 0); test_end(); test_begin("binary to hex ucase"); test_assert(strcmp(binary_to_hex_ucase(input, sizeof(input)), output_ucase) == 0); test_end(); test_begin("binary to hex ucase"); str = t_str_new(32); str_append_c(str, '<'); binary_to_hex_append(str, input, sizeof(input)); str_append_c(str, '>'); test_assert(strcmp(str_c(str), t_strconcat("<", output_lcase, ">", NULL)) == 0); test_end(); }
static int client_input_status_overview(struct doveadm_connection *client) { struct replicator_queue *queue = replicator_brain_get_queue(client->brain); struct replicator_queue_iter *iter; struct replicator_user *user; enum replication_priority priority; unsigned int pending_counts[REPLICATION_PRIORITY_SYNC+1]; unsigned int user_count, next_secs, pending_failed_count; unsigned int pending_full_resync_count, waiting_failed_count; string_t *str = t_str_new(256); memset(pending_counts, 0, sizeof(pending_counts)); pending_failed_count = 0; waiting_failed_count = 0; pending_full_resync_count = 0; user_count = 0; iter = replicator_queue_iter_init(queue); while ((user = replicator_queue_iter_next(iter)) != NULL) { if (user->priority != REPLICATION_PRIORITY_NONE) pending_counts[user->priority]++; else if (replicator_queue_want_sync_now(queue, user, &next_secs)) { if (user->last_sync_failed) pending_failed_count++; else pending_full_resync_count++; } else { if (user->last_sync_failed) waiting_failed_count++; } user_count++; } replicator_queue_iter_deinit(&iter); for (priority = REPLICATION_PRIORITY_SYNC; priority > 0; priority--) { str_printfa(str, "Queued '%s' requests\t%u\n", replicator_priority_to_str(priority), pending_counts[priority]); } str_printfa(str, "Queued 'failed' requests\t%u\n", pending_failed_count); str_printfa(str, "Queued 'full resync' requests\t%u\n", pending_full_resync_count); str_printfa(str, "Waiting 'failed' requests\t%u\n", waiting_failed_count); str_printfa(str, "Total number of known users\t%u\n", user_count); str_append_c(str, '\n'); o_stream_send(client->conn.output, str_data(str), str_len(str)); return 0; }
static void reply_append_extra_fields(string_t *str, struct auth_request *request) { if (!auth_fields_is_empty(request->extra_fields)) { str_append_c(str, '\t'); auth_fields_append(request->extra_fields, str, 0, 0); } if (request->userdb_reply != NULL && auth_fields_is_empty(request->userdb_reply)) { /* all userdb_* fields had NULL values. we'll still need to tell this to the master */ str_append(str, "\tuserdb_"AUTH_REQUEST_USER_KEY_IGNORE); } }
void passdb_blocking_verify_plain(struct auth_request *request) { string_t *str; str = t_str_new(128); str_printfa(str, "PASSV\t%u\t", request->passdb->passdb->id); str_append_tabescaped(str, request->mech_password); str_append_c(str, '\t'); auth_request_export(request, str); auth_request_ref(request); auth_worker_call(request->pool, request->user, str_c(str), verify_plain_callback, request); }
void passdb_blocking_lookup_credentials(struct auth_request *request) { string_t *str; str = t_str_new(128); str_printfa(str, "PASSL\t%u\t", request->passdb->passdb->id); str_append_tabescaped(str, request->credentials_scheme); str_append_c(str, '\t'); auth_request_export(request, str); auth_request_ref(request); auth_worker_call(request->pool, request->user, str_c(str), lookup_credentials_callback, request); }
static const char * pop3c_client_get_sasl_plain_request(struct pop3c_client *client) { const struct pop3c_client_settings *set = &client->set; string_t *in, *out; in = t_str_new(128); if (set->master_user != NULL) { str_append(in, set->username); str_append_c(in, '\0'); str_append(in, set->master_user); } else { str_append_c(in, '\0'); str_append(in, set->username); } str_append_c(in, '\0'); str_append(in, set->password); out = t_str_new(128); base64_encode(str_data(in), str_len(in), out); str_append(out, "\r\n"); return str_c(out); }
void qp_encoder_more(struct qp_encoder *qp, const void *_src, size_t src_size) { const unsigned char *src = _src; i_assert(_src != NULL || src_size == 0); if (src_size == 0) return; if (qp->add_header_preamble) { size_t used = qp->dest->used; qp->add_header_preamble = FALSE; str_append(qp->dest, "=?utf-8?Q?"); qp->line_len = qp->dest->used - used; } for(unsigned int i = 0; i < src_size; i++) { unsigned char c = src[i]; /* if input is not binary data and we encounter newline convert it as crlf, or if the last byte was CR, preserve CRLF */ if (c == '\n' && ((qp->flags & (QP_ENCODER_FLAG_BINARY_DATA|QP_ENCODER_FLAG_HEADER_FORMAT)) == 0 || qp->cr_last)) { str_append_c(qp->dest, '\r'); str_append_c(qp->dest, '\n'); /* reset line length here */ qp->line_len = 0; qp->cr_last = FALSE; continue; } else if (qp->cr_last) { qp_encode_or_break(qp, '\r'); qp->cr_last = FALSE; } if (c == '\r') { qp->cr_last = TRUE; } else { qp_encode_or_break(qp, c); } } }