std::string
    ValueGenerator::generate_string( std::vector<int> constraints )
  {
    std::string random_string;
    int min_size = constraints[ MIN_SIZE ];
    int max_size = constraints[ MAX_SIZE ];

    switch( verify_type_constraint( constraints ) )
    {
      case NULLABLE:
        random_string = null;
        break;
      case BLANK:
        random_string = empty_string;
        break;
      case URL:
        random_string = generate_random_url( min_size, max_size );
        break;
      case EMAIL:
        random_string = generate_random_email( min_size, max_size );
        break;
      case CREDIT_CARD:
        random_string = generate_random_credit_card();
        break;
      case MIN_SIZE:
      case MAX_SIZE:
      case SIZE:
        random_string = generate_random_string( min_size, max_size );
        break;
    }

    return random_string;
  }
/*
 * anonymization of octet string
 * anonymized octet strings are also kept in a linked list to make
 * sure they are unique
 *
 * astr has to be a large enough buffer where the anonymized string
 * will be copied, the anonymized string will be as long as the
 * original string
 */
int
anon_octs_map(anon_octs_t *a, const char *str, char *astr)
{
    struct hash_node node;
    struct hash_node *p;
    int tmp;

    (void) anon_octs_set_state(a, NON_LEX);

    /* lookup anon. string in lhash table */
    node.data = (char*) str;
    p = (struct hash_node *) lh_retrieve(a->hash_table,(void*) &node);

    if (p) { /* found in lhash table */
        strcpy(astr, p->hash);
    } else { /* not found in lhash table */
        /* generate a unique random string */
        do {
            generate_random_string(astr, strlen(str));
            tmp = list_insert(&(a->list),astr);
            assert(tmp >= 0);
        } while (tmp==1);
        /* store anon. string in lhash table */
        p = (struct hash_node*) malloc(sizeof(struct hash_node));
        assert(p);
        p->data = (char*) malloc(strlen(str)+1);
        assert(p->data);
        p->hash = (char*) malloc(strlen(astr)+1);
        assert(p->hash);
        strcpy(p->data, str);
        strcpy(p->hash, astr);
        lh_insert(a->hash_table, p);
    }
    return 0;
}
AudioSinksManager::InternalAudioSink::InternalAudioSink(AudioSinksManager* manager_,
                                                        std::string name_, std::string pretty_name_)
        : manager(manager_), name(name_), pretty_name(pretty_name_),
          sink_idx(static_cast<uint32_t>(-1)), state(State::NONE), default_sink(false),
          activated(false), num_sink_inputs(0) {
    identifier = generate_random_string(10);
    volume.channels = 0;
}
Exemple #4
0
void read_config()
{
	if (m_use_sql)
	{
		try
		{
			Csql_result result = Csql_query(m_database, "select name, value from @config where value is not null").execute();
			Cconfig config;
			while (Csql_row row = result.fetch_row())
			{
				if (config.set(row[0].s(), row[1].s()))
					std::cerr << "unknown config name: " << row[0].s() << std::endl;
			}
			config.load(m_conf_file);
			if (config.m_torrent_pass_private_key.empty())
			{
				config.m_torrent_pass_private_key = generate_random_string(27);
				Csql_query(m_database, "insert into @config (name, value) values ('torrent_pass_private_key', ?)")(config.m_torrent_pass_private_key).execute();
			}
			m_config = config;
			m_database.set_name("completed", m_config.m_column_files_completed);
			m_database.set_name("leechers", m_config.m_column_files_leechers);
			m_database.set_name("seeders", m_config.m_column_files_seeders);
			m_database.set_name("fid", m_config.m_column_files_fid);
			m_database.set_name("uid", m_config.m_column_users_uid);
			m_database.set_name("announce_log", m_config.m_table_announce_log.empty() ? m_table_prefix + "announce_log" : m_config.m_table_announce_log);
			m_database.set_name("files", m_config.m_table_torrents.empty() ? m_table_prefix + "files" : m_config.m_table_torrents);
			m_database.set_name("files_users", m_config.m_table_torrents_users.empty() ? m_table_prefix + "files_users" : m_config.m_table_torrents_users);
			m_database.set_name("scrape_log", m_config.m_table_scrape_log.empty() ? m_table_prefix + "scrape_log" : m_config.m_table_scrape_log);
			m_database.set_name("users", m_config.m_table_users.empty() ? m_table_prefix + "users" : m_config.m_table_users);
		}
		catch (bad_query&)
		{
		}
	}
	else
	{
		Cconfig config;
		if (!config.load(m_conf_file))
			m_config = config;
	}
	if (m_config.m_listen_ipas.empty())
		m_config.m_listen_ipas.insert(htonl(INADDR_ANY));
	if (m_config.m_listen_ports.empty())
		m_config.m_listen_ports.insert(2710);
	m_read_config_time = srv_time();
}
  std::string ValueGenerator::generate_random_value( std::string type, int min, int max, int scale )
  {
    std::string random_value;

    if( Helper::is_string( type ) )
    {
      random_value = generate_random_string( min, max );
    } else if ( Helper::is_integer( type ) )
    {
      random_value = generate_random_integer( min, max );
    } else if ( Helper::is_floating( type ) )
    {
      random_value = generate_random_floating( min, max, scale );
    } else if( Helper::is_boolean( type ) )
    {
      random_value = generate_boolean();
    }

    return random_value;
  }
Exemple #6
0
/******************************************************************************
* extract_files: extract and restore files from binary. 
*
* @param hwnd: handle to window 
*
******************************************************************************/
static int 
extract_files(HWND hwnd)
{
    char *unix_style_work_dir_path, *command = NULL;
    char *work_dir_path;
    int command_length = 0;
    char *pch1, *pch2, *pch3;
    int i, j;

    log_message("Base extraction path: %s\n", temp_dir_path);

    /* Create the path to the work directory */
    if (g_user_path == NULL)
    {
        work_dir_path = allocate_string_buffer(strlen(temp_dir_path) + strlen(work_dir_basename) + RANDOM_STRING_LEN + strlen(DIRSEPSTR));
       
        if (work_dir_path == NULL)
        {
            fclose(g_logFile);
            if (g_console_install == FALSE || g_nosplash == FALSE)
            {
                sprintf(msg_box_string, "%s%s%s", "Error extracting files\nUnable to allocate memory\n\n", "See the log file at:\n\n", sfx_log_file);
                MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                SendMessage(hwnd, WM_DESTROY, 0, 0);
            }
            exit(20);
        }

        if (g_env_var_path == NULL)
        {
            strcpycat(temp_dir_path, work_dir_basename, work_dir_path);
            srand(time(NULL));
            generate_random_string(work_dir_path, strlen(work_dir_path), RANDOM_STRING_LEN);
        }
        else
        {
            strcpy(work_dir_path, temp_dir_path);
        }
        strcat(work_dir_path, DIRSEPSTR);
    }
    else
    {
       log_message("User path: %s\n", g_user_path);

        if (g_user_path[strlen(g_user_path) - 1] != '\\')
        {
            work_dir_path = allocate_string_buffer(strlen(g_user_path) + strlen(DIRSEPSTR));
            if (work_dir_path == NULL)
            {
                fclose(g_logFile);
                if (g_console_install == FALSE || g_nosplash == FALSE)
                {
                    sprintf(msg_box_string, "%s%s%s", "Error extracting files\nUnable to allocate memory\n\n", "See the log file at:\n\n", sfx_log_file);
                    MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                    SendMessage(hwnd, WM_DESTROY, 0, 0);
                }
                exit(21);
            }
            strcpycat(g_user_path, DIRSEPSTR, work_dir_path);
        }
        else
        {
            work_dir_path = g_user_path;
        }
    }

    log_message("Extraction path: %s\n", work_dir_path);

    /* Create the work directory */
    if (!file_exists (work_dir_path))
        if (make_path (work_dir_path, 0777) != 0)
        {
            log_message("Could not create directory: %s\n", work_dir_path);
            fclose(g_logFile);
            if (g_console_install == FALSE || g_nosplash == FALSE)
            {
                sprintf(msg_box_string, "%s%s%s", "Error extracting files\nUnable to create directory\n\n", "See the log file at:\n\n", sfx_log_file);
                MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                SendMessage(hwnd, WM_DESTROY, 0, 0);
            }
        exit(22);
        }

    /* Create unix style work dir path */
    unix_style_work_dir_path = replace_sub_string(work_dir_path, DIRSEPSTR, "/");
    if (unix_style_work_dir_path == NULL)
    {
        log_message("Could not allocate memory for directory path\n");
        fclose(g_logFile);
        if (g_console_install == FALSE || g_nosplash == FALSE)
        {
            sprintf(msg_box_string, "%s%s%s", "Error extracting files\nUnable to allocate memory\n\n", "See the log file at:\n\n", sfx_log_file);
            MessageBox(hwnd, msg_box_string, NULL, MB_OK);
            SendMessage(hwnd, WM_DESTROY, 0, 0);
        }
        exit(23);
    }

    log_message("Extracting bundles ...\n");

    /* Process bundles */
    for (i = 0; i < P2_SFX_NUM_BUNDLES; i++)
    {
        char *installer_dir_path;

        installer_dir_path = allocate_string_buffer(strlen(work_dir_path) + strlen(bundles[i].path));
        if (installer_dir_path == NULL)
        {
            fclose(g_logFile);
            if (g_console_install == FALSE || g_nosplash == FALSE)
            {
                sprintf(msg_box_string, "%s%s%s", "Error extracting files\nUnable to allocate memory\n\n", "See the log file at:\n\n", sfx_log_file);
                MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                SendMessage(hwnd, WM_DESTROY, 0, 0);
            }
            exit(24);
        }

        /* Create path to file */
        strcpycat(work_dir_path, bundles[i].path, installer_dir_path);
        for (j = 0; j < bundles[i].num_file_descs; j++)
        {
            P2_SFX_FILE_DESC *file_desc = &(bundles[i].files[j]);

            if (write_file_desc(file_desc, installer_dir_path))
            {
                fclose(g_logFile);
                if (g_console_install == FALSE || g_nosplash == FALSE)
                {
                    sprintf(msg_box_string, "%s%s%s", "Error extracting files\nPossibly check available disk space.\n\n", "See the log file at:\n\n", sfx_log_file);
                    MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                    SendMessage(hwnd, WM_DESTROY, 0, 0);
                }
                exit(25);
            }
        }
        free(installer_dir_path);

        /* Process commands */
        for (j = 0; j < bundles[i].num_commands; j++)
        {
            char *setupexe;

            setupexe = NULL;

            /* Check to see if command contains setup */
            pch3 = strstr(bundles[i].commands[j], SETUP);

            if (pch3 != NULL)
            {
                if (g_console_install == FALSE)
                {          
                    setupexe = replace_sub_string(bundles[i].commands[j], SETUP, GUI_SETUP_COMMAND);
                }
                else
                {
                    setupexe = replace_sub_string(bundles[i].commands[j], SETUP, CONSOLE_SETUP_COMMAND);
                }
            }

            /* If the command contains setup.exe and there is no user path 
               or if it is any other command that doesn't contain setup */
            if ((setupexe != NULL && g_user_path == NULL) ||
                 setupexe == NULL)
            {
                char * tmp;
                int string_length;

                /* Substitute windows style path */
                if (setupexe == NULL)
                {
                    pch1 = replace_sub_string(bundles[i].commands[j], WINDOWS_BASE_PATH, work_dir_path);
                }
                else
                {
                    pch1 = replace_sub_string(setupexe, WINDOWS_BASE_PATH, work_dir_path);
                }

                if (pch1 == NULL)
                {
                    log_message("Error: Failed to allocate memory for windows path string\n");
                    fclose(g_logFile);
                    if (g_console_install == FALSE || g_nosplash == FALSE)
                    {
                        sprintf(msg_box_string, "%s%s%s", "Error extracting files\nUnable to allocate memory\n\n", "See the log file at:\n\n", sfx_log_file);
                        MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                        SendMessage(hwnd, WM_DESTROY, 0, 0);
                    }
                    exit(26);
                }

                /* Substitute unix style path */
                pch2 = replace_sub_string(pch1, UNIX_BASE_PATH, unix_style_work_dir_path);
                free(pch1);

                if (pch2 == NULL)
                {
                    log_message("Error: Failed to allocate memory for unix path string\n");
                    fclose(g_logFile);
                    if (g_console_install == FALSE || g_nosplash == FALSE)
                    {
                        sprintf(msg_box_string, "%s%s%s", "Error extracting files\nUnable to allocate memory\n\n", "See the log file at:\n\n", sfx_log_file);
                        MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                        SendMessage(hwnd, WM_DESTROY, 0, 0);
                    }
                    exit(27);
                }

                if (setupexe != NULL)
                {
                    char * install_once = INSTALL_ONCE;
                    char * install_log = INSTALL_LOG;
                    char * dash_data = DASH_DATA;

                    string_length = strlen(pch2) + strlen(install_once) + strlen(dash_data) + (4 * strlen("\"")) + 1;
                    string_length += strlen(install_log) + strlen(base_log_dir) + strlen(timestamp_log_dir) + 1;
                    tmp = allocate_string_buffer(string_length);
                    if (tmp == NULL)
                    {
                        log_message("Error: Failed to allocate memory for implicit arguments\n");
                        fclose(g_logFile);
                        if (g_console_install == FALSE || g_nosplash == FALSE)
                        {
                            sprintf(msg_box_string, "%s%s%s", "Error extracting files\nUnable to allocate memory\n\n", "See the log file at:\n\n", sfx_log_file);
                            MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                            SendMessage(hwnd, WM_DESTROY, 0, 0);
                        }
                        exit(28);
                    }
                    strcpy(tmp, pch2);
                    strcat(tmp, install_once);
                    strcat(tmp, install_log);
                    strcat(tmp, "\"");
                    strcat(tmp, base_log_dir);
                    strcat(tmp, "\"");
                    strcat(tmp, dash_data);
                    strcat(tmp, "\"");
                    strcat(tmp, timestamp_log_dir);
                    strcat(tmp, "\"");

                    free(pch2); 
                    pch2 = tmp;
                }

                /* Create command with g_args */
                if (setupexe != NULL && g_args != NULL)
                {
                    string_length = strlen(pch2) + strlen(g_args) + 2;
                    tmp = allocate_string_buffer(string_length);

                    if (tmp == NULL)
                    {
                        log_message("Error: Failed to allocate memory for command with arguments");
                        fclose(g_logFile);
                        if (g_console_install == FALSE || g_nosplash == FALSE)
                        {
                            sprintf(msg_box_string, "%s%s%s", "Error extracting files\nUnable to allocate memory\n\n", "See the log file at:\n\n", sfx_log_file);
                            MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                            SendMessage(hwnd, WM_DESTROY, 0, 0);
                        }
                        exit(29);
                    }
                    strcpy(tmp, pch2);
                    strcat(tmp, " ");
                    strcat(tmp, g_args);
                    free(pch2); 
                    pch2 = tmp;
                }

                if (setupexe != NULL)
                {
                    string_length = strlen(pch2) + strlen(VM_ARGS) + 
                                    strlen(VM_ARG_FILE) + strlen(timestamp_log_dir) + 3;
                    tmp = allocate_string_buffer(string_length);

                    if (tmp == NULL)
                    {
                        log_message("Error: Failed to allocate memory for vm args");
                        fclose(g_logFile);
                        if (g_console_install == FALSE || g_nosplash == FALSE)
                        {
                            sprintf(msg_box_string, "%s%s%s", "Error extracting files\nUnable to allocate memory\n\n", "See the log file at:\n\n", sfx_log_file);
                            MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                            SendMessage(hwnd, WM_DESTROY, 0, 0);
                        }
                        exit(29);
                    }

                    strcpy(tmp, pch2);
                    strcat(tmp, VM_ARGS);
                    strcat(tmp, "\"");
                    strcat(tmp, timestamp_log_dir);
                    strcat(tmp, VM_ARG_FILE);
                    strcat(tmp, "\"");
                    free(pch2); 
                    pch2 = tmp;
                }

                /* Execute command */
                log_message("Executing command: %s\n", pch2);

                if (setupexe == NULL)
                {
                    /* All non-setup commands use CreateProcess */
                    if(start_process(pch2))
                    {
                        log_message("Error: Failed to execute %s\n", pch2);
                        fclose(g_logFile);
                        if (g_console_install == FALSE || g_nosplash == FALSE)
                        {
                            sprintf(msg_box_string, "%s%s%s", "Error extracting files\nCommand failure\n\n", "See the log file at:\n\n", sfx_log_file);
                            MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                            SendMessage(hwnd, WM_DESTROY, 0, 0);
                        }
                        exit(30);
                    }
                }
                else
                {
                    /* Split the command into a "command" and "argument" format */
                    char * exestring = allocate_string_buffer(strlen(pch2));
                    char * cmdargs = allocate_string_buffer(strlen(pch2));
                    HINSTANCE return_value;

                    tmp = strstr(pch2, ".exe");
                    tmp += (strlen(".exe") + 1);
                    strncpy(exestring, pch2, strlen(pch2) - strlen(tmp));
                    exestring[strlen(pch2) - strlen(tmp)] = 0;
                    strcpy(cmdargs, tmp);

                    log_message("Installer command = %s\n", exestring);
                    log_message("Installer arguments = %s\n", cmdargs);

                    return_value = ShellExecute(NULL, "open", exestring, cmdargs, NULL, SW_SHOWNORMAL);

                    if ((int)return_value <= 32)
                    {
                        log_message("Error: ShellExecute returned a value of %d\n", (int)return_value);
                        fclose(g_logFile);
                        if (g_console_install == FALSE || g_nosplash == FALSE)
                        {
                            sprintf(msg_box_string, "%s%s%s", "Error extracting files\nCommand failure\n\n", "See the log file at:\n\n", sfx_log_file);
                            MessageBox(hwnd, msg_box_string, NULL, MB_OK);
                            SendMessage(hwnd, WM_DESTROY, 0, 0);
                        }
                        exit(31);
                    }
                    
                }

                free(pch2);
            }
        }
    }

    if (g_console_install == FALSE || g_nosplash == FALSE)
    {
        SendMessage(hwnd, WM_DESTROY, 0, 0);
    } 

    return 0;
}
static ngx_int_t
ngx_http_captcha_generate_handler(ngx_http_request_t *r)
{
    ngx_int_t    rc;
    ngx_buf_t   *b;
    ngx_chain_t  out;

    ngx_captcha_access_filter_ctx_t       *ctx    = NULL;

    ngx_str_t   response_key    = ngx_string("valor_captcha");
    ngx_str_t   response_val    = ngx_null_string;

    u_char      *buffer     = NULL;

    /* we response to 'GET' and 'HEAD' requests only */
   if (r->method & (NGX_HTTP_POST)) {
        /* Create a new context */
        ctx = ngx_pcalloc(r->pool, sizeof(ngx_captcha_access_filter_ctx_t));
        if (ctx == NULL) {
            return NGX_ERROR;
        }
        ngx_http_set_ctx(r, ctx, ngx_captcha_access_filter_module);
        /* Begin to read POST data */
        rc = ngx_http_read_client_request_body(r, ngx_http_form_input_post_read);
        if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
            return rc;
        }
        if (rc == NGX_AGAIN) {
            ctx->waiting_more_body = 1;
            return NGX_AGAIN;
        }
        /* Now we have post data */
        ngx_log_debug( NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "client request body successfully read" );

        /* Retrieve username and pasword */
        buffer = ngx_captcha_get_request_body( r );   
        if ( buffer == NULL ) {
            return NGX_HTTP_FORBIDDEN;
        }
        rc = ngx_captcha_get_request_parameter_value( r, buffer, &response_key, &response_val );
        if ( rc != NGX_OK ) {
            ngx_log_debug( NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "request parameter %s not found", response_key.data );
            return NGX_HTTP_FORBIDDEN;
        } 
        
        
        rc = verifica_captcha( r, &response_val );
        if ( rc == 0 ) {
            ngx_log_debug( NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "\n\n\n\n\ncaptcha not verified\n\n\n\n\n" );
            return NGX_HTTP_FORBIDDEN;
        }
        
    }

    if (!(r->method & (NGX_HTTP_GET))) {
        return NGX_HTTP_NOT_ALLOWED;
    }
 
    /* discard request body, since we don't need it here */
    rc = ngx_http_discard_request_body(r);
 
    if (rc != NGX_OK) {
        return rc;
    }
 
    /* set the 'Content-type' header */
    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_type.len = sizeof("image/gif") - 1;
    r->headers_out.content_type.data = (u_char *) "image/gif";
//    r->headers_out.content_length_n = 100;
    
    /* allocate a buffer for your response body */
    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
 
    /* attach this buffer to the buffer chain */
    out.buf = b;
    out.next = NULL;
    
    // Gera a imagem
    u_char resposta[7];
    u_char gif[CAPTCHA_BUFFER];
    
    resposta[6] = 0; // string em C precisam de um \0
    char chave[10] = { 0 };
    
    ngx_str_t ngx_chave = ngx_string(chave);
    ngx_str_t COMBINACOES = ngx_string("0123456789abcdefgihjk");
    
    generate_random_string(&ngx_chave, &COMBINACOES);
    
    ngx_str_t r2 = ngx_string(resposta);
    
    simple_captcha_generate(gif, &r2);
    // 
    // captcha(imagem, resposta);
    // makegif(imagem, gif);
    
    ngx_str_t cookie_name = ngx_string("CAPTCHA");
    ngx_str_t cookie_value = ngx_chave;
    
    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "Resposta captcha %s eh %s", cookie_value.data, resposta);

    write_session_cookie(r, &cookie_name, &cookie_value);
    

    // TODO Permitir configurar o tempo de expiração
    memcached_return_t mc_rc = memcached_set(memc, (char*) ngx_chave.data, ngx_chave.len, (char*)resposta, strlen((char*)resposta), (time_t) 10000, (uint32_t)0);
    if (mc_rc != MEMCACHED_SUCCESS) {
        ngx_log_error(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "Problemas ao escrever no memcached");
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    
    // FIXME Código de teste
    // ngx_str_t re = ngx_string("vswrv");
    // int v = verifica_captcha(r, &re);
    // ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
    //                "Valida captcha retornou %d", v);
    /// END

 
    /* adjust the pointers of the buffer */
    b->pos = gif;
    b->last = gif + CAPTCHA_BUFFER - 1;
    b->memory = 1;    /* this buffer is in memory */
    b->last_buf = 1;  /* this is the last buffer in the buffer chain */
 
    /* send the headers of your response */
    rc = ngx_http_send_header(r);
 
    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }
 
    /* send the buffer chain of your response */
    return ngx_http_output_filter(r, &out);
}
/*
 * generate anonymized strings preserving lexicographic-order
 *
 * only strings between start and end (including start, excluding end)
 * will be processed
 * set end to null to process list to the end
 * prev_length - length of prefixes already processed. Hence all
 * strings in the range must be longer or of equal
 * length. Furthermore, all strings in the range are expected to have
 * identical prefixes of prev_length.
 * aprefix - anonymized prefix (first prev_length chars)
 */
static int
generate_lex_anonymizations(anon_octs_t *a, size_t prev_length,
                            const char* aprefix,
                            struct node *start, struct node *end)
{
    char* str;  /* prefix up to min_length */
    char* astr; /* astr - anonymized str */
    char* prefix; /* prefix of prev_length - same for all strings in group */
    //char* aprefix; /* anonymized (hash of) prefix */
    //char* middle; /* part of string between prev_length and min_length */
    char* amiddle; /* anonymized (hash of) middle */
    struct node *p, *q; /* nodes in list */
    struct node *start2; /* recursively process this part of the list */
    size_t min_length; /* minimum string length in our part of list */
    int count; /* number of unique prefixes (of min_length) */
    struct node* hashlist = NULL; /* stores generated amiddle's */
    struct node *hp; /* nodes in hash list */
    struct hash_node* node = NULL; /* lhash table node */
    int i;

    assert(a);
    if (!start)
        return 0;
    assert(aprefix || prev_length > 0);

    /* find min length */
    min_length = strlen(start->data);
    for (p = start; p && p!=end; p = p->next) {
        int tmp = strlen(p->data);
        if (tmp < min_length) {
            min_length = tmp;
        }
    }
    assert(min_length > prev_length);

    /* count unique prefixes of min_length (after position prev_length) */
    count = 0;
    for (p = start, q = NULL; p && p!=end; q = p, p = p->next) {
        if (q) {
            if (strncmp(p->data+prev_length, q->data+prev_length,
                        min_length-prev_length)) {
                count++;
            }
        } else { /* first element in list */
            count++;
        }
    }

    /*  produce hashlist (amiddle) */
    for (i=0; i<count; i++) {
        do {
            amiddle = (char*) malloc(min_length-prev_length+1);
            amiddle = generate_random_string(amiddle, min_length-prev_length);
        } while (list_insert(&hashlist,amiddle)==1);
    }

    /* assign anon. strings to real strings and store them in lhash table */
    str = (char*) malloc(min_length+1);
    astr = (char*) malloc(min_length+1);
    assert(str);
    assert(astr);
    hp = hashlist;
    int group_size = 0; /* size of last group
			 * excluding min_lenght element (if it exists)
			 */
    int is_diff = 0; /* is current string (p) different from previous one (q)
		      * up to min_length?
		      */
    int was_minlength = 0; /* if last group contained (==started with)
			    * a string of min_length
			    * - determines if we need to allocate new str, astr
			    */
    start2 = start;
    for (p = start, q = NULL; p && p!=end; q = p, p = p->next) {
        /*
        fprintf(stderr, "assigning %s (hp: %s)...\n",
        	p->data, (hp)?hp->data:"NULL");
        */
        assert(strlen(p->data) >= min_length);
        /* check if p is different from q up to first min_length chars */
        is_diff = 0;
        if (q) {
            if (strncmp(p->data+prev_length, q->data+prev_length,
                        min_length-prev_length)) {
                is_diff = 1;
            } else {
                group_size++;
            }
        } else {
            /* first item in list */
            is_diff = 1;
        }
        if (is_diff) {
            if (q) { /* don't call for first item in list */
                /* anonymize the previous group */
                if (group_size > 0) {
                    assert(strlen(start2->data) > min_length);
                    generate_lex_anonymizations(a, min_length, astr,
                                                start2, p);
                }
                if (was_minlength) {
                    str = (char*) malloc(min_length+1);
                    astr = (char*) malloc(min_length+1);
                    assert(str);
                    assert(astr);
                }
            }
            start2 = p;
            /* prepare str, astr */
            strncpy(str, p->data, min_length);
            str[min_length] = '\0';
            /* aprefix generated earlier and passed as a function argument */
            strncpy(astr, aprefix, prev_length);
            assert(hp);
            assert(hp->data);
            strncpy(astr+prev_length, hp->data, min_length-prev_length);
            astr[min_length] = '\0';

            if (strlen(p->data) == min_length) {
                /* store (str, astr) in lhash */
                node = (struct hash_node*) malloc(sizeof(struct hash_node));
                assert(node);
                node->data = str;
                node->hash = astr;
                /*
                fprintf(stderr, "storing in hash table [%s --> %s]\n",
                	str, astr);
                */
                lh_insert(a->hash_table, node);
                /* omit this (min_length) element from recursion */
                start2 = p->next;
                was_minlength = 1;
                group_size = 0;
            } else {
                /* don't need to store (str, astr) in lhash */
                was_minlength = 0;
                group_size = 1;
            }
            /* advance to next node in hashlist */
            hp = hp->next;

        } /* else do nothing */
    }
    if (start2 && group_size > 0) {
        assert(strlen(start2->data) > min_length);
        generate_lex_anonymizations(a, min_length, astr, start2, end);
    }
    if (was_minlength) {
        str = (char*) malloc(min_length+1);
        astr = (char*) malloc(min_length+1);
        assert(str);
        assert(astr);
    }

    /* we don't need the list of used strings anymore */
    //list_remove_all(&(a->list));
    list_remove_all(&hashlist);
    free(str);
    free(astr);
    return 0;
}