/*
This file is part of GNUnet.
- Copyright (C) 2011 - 2013 GNUnet e.V.
+ Copyright (C) 2011 - 2017 GNUnet e.V.
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ Affero General Public License for more details.
*/
/**
/*************************** TESTBED PEER SETUP *****************************/
/******************************************************************************/
+/**
+ * Process the text buffer counting the non-empty lines and separating them
+ * with NULL characters, for later ease of copy using (as)printf.
+ *
+ * @param data Memory buffer with strings.
+ * @param data_size Size of the @a data buffer in bytes.
+ * @param str_max Maximum number of strings to return.
+ * @return Positive number of lines found in the buffer,
+ * #GNUNET_SYSERR otherwise.
+ */
+static int
+count_and_separate_strings (char *data,
+ uint64_t data_size,
+ unsigned int str_max)
+{
+ char *buf; // Keep track of last string to skip blank lines
+ unsigned int offset;
+ unsigned int str_cnt;
+
+ buf = data;
+ offset = 0;
+ str_cnt = 0;
+ while ( (offset < (data_size - 1)) && (str_cnt < str_max) )
+ {
+ offset++;
+ if ( ((data[offset] == '\n')) &&
+ (buf != &data[offset]) )
+ {
+ data[offset] = '\0';
+ str_cnt++;
+ buf = &data[offset + 1];
+ }
+ else if ( (data[offset] == '\n') ||
+ (data[offset] == '\0') )
+ buf = &data[offset + 1];
+ }
+ return str_cnt;
+}
+
+
+/**
+ * Allocate a string array and fill it with the prefixed strings
+ * from a pre-processed, NULL-separated memory region.
+ *
+ * @param data Preprocessed memory with strings
+ * @param data_size Size of the @a data buffer in bytes.
+ * @param strings Address of the string array to be created.
+ * Must be freed by caller if function end in success.
+ * @param str_cnt String count. The @a data buffer should contain
+ * at least this many NULL-separated strings.
+ * @return #GNUNET_OK in ase of success, #GNUNET_SYSERR otherwise.
+ * In case of error @a strings must not be freed.
+ */
+static int
+create_string_array (char *data, uint64_t data_size,
+ char ***strings, unsigned int str_cnt)
+{
+ uint64_t offset;
+ uint64_t len;
+ unsigned int i;
+
+ *strings = GNUNET_malloc (sizeof (char *) * str_cnt);
+ offset = 0;
+ for (i = 0; i < str_cnt; i++)
+ {
+ len = strlen (&data[offset]);
+ if (offset + len >= data_size)
+ {
+ GNUNET_free (*strings);
+ *strings = NULL;
+ return GNUNET_SYSERR;
+ }
+ if (0 == len) // empty line
+ {
+ offset++;
+ i--;
+ continue;
+ }
+
+ GNUNET_asprintf (&(*strings)[i],
+ "%s%s",
+ regex_prefix,
+ &data[offset]);
+ offset += len + 1;
+ }
+ return GNUNET_OK;
+}
+
/**
* Load search strings from given filename. One search string per line.
unsigned int limit)
{
char *data;
- char *buf;
uint64_t filesize;
- unsigned int offset;
int str_cnt;
- unsigned int i;
+ /* Sanity checks */
if (NULL == filename)
{
return GNUNET_SYSERR;
}
-
if (GNUNET_YES != GNUNET_DISK_file_test (filename))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
&filesize,
GNUNET_YES,
GNUNET_YES))
- filesize = 0;
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Search strings file %s cannot be read.\n",
+ filename);
+ return GNUNET_SYSERR;
+ }
if (0 == filesize)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
filename);
return GNUNET_SYSERR;
}
+
+ /* Read data into memory */
data = GNUNET_malloc (filesize + 1);
if (filesize != GNUNET_DISK_fn_read (filename,
data,
filename);
return GNUNET_SYSERR;
}
- buf = data;
- offset = 0;
- str_cnt = 0;
- while ( (offset < (filesize - 1)) && (str_cnt < limit) )
- {
- offset++;
- if ( ((data[offset] == '\n')) &&
- (buf != &data[offset]) )
- {
- data[offset] = '\0';
- str_cnt++;
- buf = &data[offset + 1];
- }
- else if ( (data[offset] == '\n') ||
- (data[offset] == '\0') )
- buf = &data[offset + 1];
- }
- *strings = GNUNET_malloc (sizeof (char *) * str_cnt);
- offset = 0;
- for (i = 0; i < str_cnt; i++)
+
+ /* Process buffer and build array */
+ str_cnt = count_and_separate_strings (data, filesize, limit);
+ if (GNUNET_OK != create_string_array (data, filesize, strings, str_cnt))
{
- GNUNET_asprintf (&(*strings)[i],
- "%s%s",
- regex_prefix,
- &data[offset]);
- offset += strlen (&data[offset]) + 1;
+ str_cnt = GNUNET_SYSERR;
}
GNUNET_free (data);
return str_cnt;
int
main (int argc, char *const *argv)
{
- static const struct GNUNET_GETOPT_CommandLineOption options[] = {
- {'o', "output-file", "FILENAME",
- gettext_noop ("name of the file for writing statistics"),
- GNUNET_YES, &GNUNET_GETOPT_set_string, &data_filename},
- {'t', "matching-timeout", "TIMEOUT",
- gettext_noop ("wait TIMEOUT before ending the experiment"),
- GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &search_timeout_time},
- {'p', "policy-dir", "DIRECTORY",
- gettext_noop ("directory with policy files"),
- GNUNET_YES, &GNUNET_GETOPT_set_filename, &policy_dir},
- {'s', "strings-file", "FILENAME",
- gettext_noop ("name of file with input strings"),
- GNUNET_YES, &GNUNET_GETOPT_set_filename, &strings_file},
- {'H', "hosts-file", "FILENAME",
- gettext_noop ("name of file with hosts' names"),
- GNUNET_YES, &GNUNET_GETOPT_set_filename, &hosts_file},
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+
+ GNUNET_GETOPT_option_filename ('o',
+ "output-file",
+ "FILENAME",
+ gettext_noop ("name of the file for writing statistics"),
+ &data_filename),
+
+ GNUNET_GETOPT_option_relative_time ('t',
+ "matching-timeout",
+ "TIMEOUT",
+ gettext_noop ("wait TIMEOUT before ending the experiment"),
+ &search_timeout_time),
+
+ GNUNET_GETOPT_option_filename ('p',
+ "policy-dir",
+ "DIRECTORY",
+ gettext_noop ("directory with policy files"),
+ &policy_dir),
+
+
+ GNUNET_GETOPT_option_filename ('s',
+ "strings-file",
+ "FILENAME",
+ gettext_noop ("name of file with input strings"),
+ &strings_file),
+
+ GNUNET_GETOPT_option_filename ('H',
+ "hosts-file",
+ "FILENAME",
+ gettext_noop ("name of file with hosts' names"),
+ &hosts_file),
+
GNUNET_GETOPT_OPTION_END
};
int ret;