bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include "lib.h"
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include "array.h"
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen#include "file-lock.h"
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include "istream.h"
7ef3553585e556f35d5919589cfdc1de3329e4bbTimo Sirainen#include "time-util.h"
087b8ac8c65a5e96a95da506450a91e8f52ae4eeTimo Sirainen#include "unichar.h"
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include "squat-trie.h"
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include "squat-uidlist.h"
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include <stdio.h>
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include <unistd.h>
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include <fcntl.h>
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include <time.h>
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen#include <sys/time.h>
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainenstatic void result_print(ARRAY_TYPE(seq_range) *result)
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen{
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen const struct seq_range *range;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen unsigned int i, count;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen range = array_get(result, &count);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen for (i = 0; i < count; i++) {
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen if (i != 0)
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen printf(",");
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen printf("%u", range[i].seq1);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen if (range[i].seq1 != range[i].seq2)
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen printf("-%u", range[i].seq2);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen }
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen printf("\n");
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen}
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainenint main(int argc ATTR_UNUSED, char *argv[])
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen{
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen const char *trie_path = "/tmp/squat-test-index.search";
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen const char *uidlist_path = "/tmp/squat-test-index.search.uids";
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen struct squat_trie *trie;
e62f6437a4ff01d692a5a61369fe4168d69191edTimo Sirainen struct squat_trie_build_context *build_ctx;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen struct istream *input;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen struct stat trie_st, uidlist_st;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen ARRAY_TYPE(seq_range) definite_uids, maybe_uids;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen char *line, *str, buf[4096];
087b8ac8c65a5e96a95da506450a91e8f52ae4eeTimo Sirainen buffer_t *valid;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen int ret, fd;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen unsigned int last = 0, seq = 1, node_count, uidlist_count;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t len;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen enum squat_index_type index_type;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen bool data_header = TRUE, first = TRUE, skip_body = FALSE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen bool mime_header = TRUE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen size_t trie_mem, uidlist_mem;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen clock_t clock_start, clock_end;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen struct timeval tv_start, tv_end;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen double cputime;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen lib_init();
46b823ac3bce2c0f9f0fc73911e48d3a77b04fbeTimo Sirainen i_unlink_if_exists(trie_path);
46b823ac3bce2c0f9f0fc73911e48d3a77b04fbeTimo Sirainen i_unlink_if_exists(uidlist_path);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen trie = squat_trie_init(trie_path, time(NULL),
d9a7e950a9cd21f2b4a90ec7759fca9e8fcc7995Timo Sirainen FILE_LOCK_METHOD_FCNTL, 0, 0600, (gid_t)-1);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen clock_start = clock();
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen gettimeofday(&tv_start, NULL);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen fd = open(argv[1], O_RDONLY);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen if (fd == -1)
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen return 1;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (squat_trie_build_init(trie, &build_ctx) < 0)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen return 1;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
087b8ac8c65a5e96a95da506450a91e8f52ae4eeTimo Sirainen valid = buffer_create_dynamic(default_pool, 4096);
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi input = i_stream_create_fd(fd, (size_t)-1);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen ret = 0;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen while (ret == 0 && (line = i_stream_read_next_line(input)) != NULL) {
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen if (last != input->v_offset/(1024*100)) {
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen fprintf(stderr, "\r%ukB", (unsigned)(input->v_offset/1024));
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen fflush(stderr);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen last = input->v_offset/(1024*100);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen }
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen if (strncmp(line, "From ", 5) == 0) {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (!first)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen seq++;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen data_header = TRUE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen skip_body = FALSE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen mime_header = TRUE;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen continue;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen }
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen first = FALSE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (strncmp(line, "--", 2) == 0) {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen skip_body = FALSE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen mime_header = TRUE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen }
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (mime_header) {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (*line == '\0') {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen data_header = FALSE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen mime_header = FALSE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen continue;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen }
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (strncasecmp(line, "Content-Type:", 13) == 0 &&
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen strncasecmp(line, "Content-Type: text/", 19) != 0 &&
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen strncasecmp(line, "Content-Type: message/", 22) != 0)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen skip_body = TRUE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen else if (strncasecmp(line, "Content-Transfer-Encoding: base64", 33) == 0)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen skip_body = TRUE;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen } else if (skip_body)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen continue;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (*line == '\0')
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen continue;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
ec83cfdc3fbcb9cbd55110e37783946a4bc0b656Timo Sirainen /* we're actually indexing here headers as bodies and bodies
ec83cfdc3fbcb9cbd55110e37783946a4bc0b656Timo Sirainen as headers. it doesn't really matter in this test, and
ec83cfdc3fbcb9cbd55110e37783946a4bc0b656Timo Sirainen fixing it would require storing headers temporarily
ec83cfdc3fbcb9cbd55110e37783946a4bc0b656Timo Sirainen elsewhere and index them only after the body */
ec83cfdc3fbcb9cbd55110e37783946a4bc0b656Timo Sirainen index_type = !data_header ? SQUAT_INDEX_TYPE_HEADER :
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen SQUAT_INDEX_TYPE_BODY;
087b8ac8c65a5e96a95da506450a91e8f52ae4eeTimo Sirainen
087b8ac8c65a5e96a95da506450a91e8f52ae4eeTimo Sirainen buffer_set_used_size(valid, 0);
2a8e2b9e3d92fd6449aa576369a5eb8b6b2b9c14Timo Sirainen len = strlen(line);
2a8e2b9e3d92fd6449aa576369a5eb8b6b2b9c14Timo Sirainen if (uni_utf8_get_valid_data((const unsigned char *)line,
2a8e2b9e3d92fd6449aa576369a5eb8b6b2b9c14Timo Sirainen len, valid)) {
2a8e2b9e3d92fd6449aa576369a5eb8b6b2b9c14Timo Sirainen ret = squat_trie_build_more(build_ctx, seq, index_type,
2a8e2b9e3d92fd6449aa576369a5eb8b6b2b9c14Timo Sirainen (const void *)line, len);
2a8e2b9e3d92fd6449aa576369a5eb8b6b2b9c14Timo Sirainen } else if (valid->used > 0) {
087b8ac8c65a5e96a95da506450a91e8f52ae4eeTimo Sirainen ret = squat_trie_build_more(build_ctx, seq, index_type,
087b8ac8c65a5e96a95da506450a91e8f52ae4eeTimo Sirainen valid->data, valid->used);
087b8ac8c65a5e96a95da506450a91e8f52ae4eeTimo Sirainen }
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen }
087b8ac8c65a5e96a95da506450a91e8f52ae4eeTimo Sirainen buffer_free(&valid);
1caf757864e7734345660e7d190f84e42668a6f8Timo Sirainen if (squat_trie_build_deinit(&build_ctx, NULL) < 0)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen ret = -1;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (ret < 0) {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen printf("build broken\n");
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen return 1;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen }
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen clock_end = clock();
ab9be857a5ae00ac114ce00815509676ef972787Aki Tuomi (void)gettimeofday(&tv_end, NULL);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen cputime = (double)(clock_end - clock_start) / CLOCKS_PER_SEC;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen fprintf(stderr, "\n - Index time: %.2f CPU seconds, "
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen "%.2f real seconds (%.02fMB/CPUs)\n", cputime,
7ef3553585e556f35d5919589cfdc1de3329e4bbTimo Sirainen timeval_diff_msecs(&tv_end, &tv_start)/1000.0,
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen input->v_offset / cputime / (1024*1024));
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (stat(trie_path, &trie_st) < 0)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen i_error("stat(%s) failed: %m", trie_path);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if (stat(uidlist_path, &uidlist_st) < 0)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen i_error("stat(%s) failed: %m", uidlist_path);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen trie_mem = squat_trie_mem_used(trie, &node_count);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen uidlist_mem = squat_uidlist_mem_used(squat_trie_get_uidlist(trie),
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen &uidlist_count);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen fprintf(stderr, " - memory: %uk for trie, %uk for uidlist\n",
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen (unsigned)(trie_mem/1024), (unsigned)(uidlist_mem/1024));
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen fprintf(stderr, " - %"PRIuUOFF_T" bytes in %u nodes (%.02f%%)\n",
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen trie_st.st_size, node_count,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen trie_st.st_size / (float)input->v_offset * 100.0);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen fprintf(stderr, " - %"PRIuUOFF_T" bytes in %u UID lists (%.02f%%)\n",
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen uidlist_st.st_size, uidlist_count,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen uidlist_st.st_size / (float)input->v_offset * 100.0);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen fprintf(stderr, " - %"PRIuUOFF_T" bytes total of %"
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen PRIuUOFF_T" (%.02f%%)\n",
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen (trie_st.st_size + uidlist_st.st_size), input->v_offset,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen (trie_st.st_size + uidlist_st.st_size) /
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen (float)input->v_offset * 100.0);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen i_stream_unref(&input);
c31803dcbdf3d4e3b836134a2a04ee2cd5251ce5Aki Tuomi i_close_fd(&fd);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen i_array_init(&definite_uids, 128);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen i_array_init(&maybe_uids, 128);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen while ((str = fgets(buf, sizeof(buf), stdin)) != NULL) {
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen ret = strlen(str)-1;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen str[ret] = 0;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen gettimeofday(&tv_start, NULL);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen ret = squat_trie_lookup(trie, str, SQUAT_INDEX_TYPE_HEADER |
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen SQUAT_INDEX_TYPE_BODY,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen &definite_uids, &maybe_uids);
2a8e2b9e3d92fd6449aa576369a5eb8b6b2b9c14Timo Sirainen if (ret < 0)
2a8e2b9e3d92fd6449aa576369a5eb8b6b2b9c14Timo Sirainen printf("error\n");
2a8e2b9e3d92fd6449aa576369a5eb8b6b2b9c14Timo Sirainen else {
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen gettimeofday(&tv_end, NULL);
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen printf(" - Search took %.05f CPU seconds\n",
ba77fee05de8b4ffdb2b51b7840b21f46e174208Timo Sirainen timeval_diff_usecs(&tv_end, &tv_start)/1000000.0);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen printf(" - definite uids: ");
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen result_print(&definite_uids);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen printf(" - maybe uids: ");
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen result_print(&maybe_uids);
2a8e2b9e3d92fd6449aa576369a5eb8b6b2b9c14Timo Sirainen }
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen }
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen return 0;
74ab5ea66c0c4b388f1c774ae6a47ab94f1b4f18Timo Sirainen}