[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Split strings into fields nondestructively.
From: |
James Youngman |
Subject: |
[PATCH] Split strings into fields nondestructively. |
Date: |
Mon, 13 Jun 2011 23:55:15 +0100 |
* lib/splitstring.c: New file; defines splitstring(), which will
non-destructively locate character-separated fields in a string.
* lib/splitstring.h: New file; declares splitstring.
* lib/test_splitstring.c: New file; unit test for splitstring.c.
* lib/nextelem.c: Delete (obsoleted by splitstring.c).
* lib/nextelem.h: Delete (obsoleted by splitstring.h).
* lib/Makefile.am (libfind_a_SOURCES): Add splitstring.c,
splitstring.c. Remove nextelem.c, nextelem.h.
(check_PROGRAMS): Add test_splitstring.
(TESTS): Add test_splitstring.
(test_splitstring_SOURCES): Sources for the
test_splitstring unit test.
* locate/locate.c: Include splitstring.h rather than nextelem.h.
(dolocate): Use splitstring rather than next_element. In places
where we need a nul-terminated string, use strndup() to create it.
Convert some space-tab sequences to regular spacing.
* find/parser.c: Include splitstring.h rather than nextelem.h.
(check_path_safety): Use splitstring rather than next_element.
* import-gnulib.config (modules): Depend on the module strndup.
* cfg.mk: Exempt lib/test_splitstring.c from calling
bindtextdomain or set_program_name.
---
ChangeLog | 25 ++++++
cfg.mk | 4 +-
find/parser.c | 32 +++++---
import-gnulib.config | 1 +
lib/Makefile.am | 14 ++--
lib/nextelem.c | 85 --------------------
lib/nextelem.h | 26 ------
lib/splitstring.c | 60 ++++++++++++++
lib/splitstring.h | 40 ++++++++++
lib/test_splitstring.c | 201 ++++++++++++++++++++++++++++++++++++++++++++++++
locate/locate.c | 61 +++++++++-----
11 files changed, 396 insertions(+), 153 deletions(-)
delete mode 100644 lib/nextelem.c
delete mode 100644 lib/nextelem.h
create mode 100644 lib/splitstring.c
create mode 100644 lib/splitstring.h
create mode 100644 lib/test_splitstring.c
diff --git a/ChangeLog b/ChangeLog
index 827ea60..7b2dd52 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,30 @@
2011-06-13 James Youngman <address@hidden>
+ Split strings into fields nondestructively.
+ * lib/splitstring.c: New file; defines splitstring(), which will
+ non-destructively locate character-separated fields in a string.
+ * lib/splitstring.h: New file; declares splitstring.
+ * lib/test_splitstring.c: New file; unit test for splitstring.c.
+ * lib/nextelem.c: Delete (obsoleted by splitstring.c).
+ * lib/nextelem.h: Delete (obsoleted by splitstring.h).
+ * lib/Makefile.am (libfind_a_SOURCES): Add splitstring.c,
+ splitstring.c. Remove nextelem.c, nextelem.h.
+ (check_PROGRAMS): Add test_splitstring.
+ (TESTS): Add test_splitstring.
+ (test_splitstring_SOURCES): Sources for the
+ test_splitstring unit test.
+ * locate/locate.c: Include splitstring.h rather than nextelem.h.
+ (dolocate): Use splitstring rather than next_element. In places
+ where we need a nul-terminated string, use strndup() to create it.
+ Convert some space-tab sequences to regular spacing.
+ * find/parser.c: Include splitstring.h rather than nextelem.h.
+ (check_path_safety): Use splitstring rather than next_element.
+ * import-gnulib.config (modules): Depend on the module strndup.
+ * cfg.mk: Exempt lib/test_splitstring.c from calling
+ bindtextdomain or set_program_name.
+
+2011-06-13 James Youngman <address@hidden>
+
Fix compilation failure in bigram.c by including <locale.h>.
* locate/bigram.c: Include <locale.h>.
diff --git a/cfg.mk b/cfg.mk
index f301884..121c337 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -36,13 +36,15 @@ exclude_file_name_regexp--sc_trailing_blank = \
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
^(.*/testsuite/.*\.(xo|xi|xe))|COPYING|doc/regexprops\.texi|m4/order-(bad|good)\.bin$$
exclude_file_name_regexp--sc_bindtextdomain = \
- ^lib/regexprops\.c$$
+ ^lib/(regexprops|test_splitstring)\.c$$
exclude_file_name_regexp--sc_prohibit_always_true_header_tests = \
^(build-aux/src-sniff\.py)|ChangeLog$$
exclude_file_name_regexp--sc_prohibit_test_minus_ao = \
^(ChangeLog)|((find|locate|xargs)/testsuite/.*\.exp)$$
exclude_file_name_regexp--sc_prohibit_doubled_word = \
^(xargs/testsuite/xargs\.sysv/iquotes\.xo)|ChangeLog|po/.*\.po$$
+exclude_file_name_regexp--sc_program_name = \
+ ^lib/test_splitstring\.c$$
# sc_texinfo_acronym: perms.texi from coreutils uses @acronym{GNU}.
exclude_file_name_regexp--sc_texinfo_acronym = doc/perm\.texi
diff --git a/find/parser.c b/find/parser.c
index 7b82ae7..ea676bd 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -34,7 +34,6 @@
#include "xalloc.h"
#include "quotearg.h"
#include "buildcmd.h"
-#include "nextelem.h"
#include "regextype.h"
#include "stat-time.h"
#include "xstrtod.h"
@@ -44,6 +43,7 @@
#include "findutils-version.h"
#include "safe-atoi.h"
#include "fdleak.h"
+#include "splitstring.h"
#include <fcntl.h>
@@ -3227,11 +3227,16 @@ make_segment (struct segment **segment,
return &(*segment)->next;
}
+
+
+
static void
check_path_safety (const char *action, char **argv)
{
- char *s;
const char *path = getenv ("PATH");
+ const char *path_separators = ":";
+ size_t pos, len;
+
if (NULL == path)
{
/* $PATH is not set. Assume the OS default is safe.
@@ -3242,34 +3247,35 @@ check_path_safety (const char *action, char **argv)
return;
}
- (void)argv;
-
- s = next_element (path, 1);
- while ((s = next_element ((char *) NULL, 1)) != NULL)
+ splitstring (path, path_separators, true, &pos, &len);
+ do
{
- if (0 == strcmp (s, "."))
+ if (0 == len || (1 == len && path[pos] == '.'))
{
+ /* empty field signifies . */
error (EXIT_FAILURE, 0,
_("The current directory is included in the PATH "
"environment variable, which is insecure in "
"combination with the %s action of find. "
"Please remove the current directory from your "
- "$PATH (that is, remove \".\" or leading or trailing "
- "colons)"),
+ "$PATH (that is, remove \".\", doubled colons, "
+ "or leading or trailing colons)"),
action);
}
- else if ('/' != s[0])
+ else if (path[pos] != '/')
{
- /* Relative paths are also dangerous in $PATH. */
+ char *relpath = strndup (&path[pos], len);
error (EXIT_FAILURE, 0,
_("The relative path %s is included in the PATH "
"environment variable, which is insecure in "
"combination with the %s action of find. "
"Please remove that entry from $PATH"),
- safely_quote_err_filename (0, s),
+ safely_quote_err_filename (0, relpath ? relpath : &path[pos]),
action);
+ /*NOTREACHED*/
+ free (relpath);
}
- }
+ } while (splitstring (path, path_separators, false, &pos, &len));
}
diff --git a/import-gnulib.config b/import-gnulib.config
index 5fb46c2..567d66c 100644
--- a/import-gnulib.config
+++ b/import-gnulib.config
@@ -132,6 +132,7 @@ strcasestr
strdup-posix
strftime
string
+strndup
strtol
strtoul
strtoull
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f8ff625..5450e9a 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -6,7 +6,7 @@ AM_CFLAGS = $(WARN_CFLAGS)
noinst_LIBRARIES = libfind.a
-check_PROGRAMS = regexprops
+check_PROGRAMS = regexprops test_splitstring
check_SCRIPTS = check-regexprops
regexprops_SOURCES = regexprops.c regextype.c
@@ -15,7 +15,7 @@ if CROSS_COMPILING
# The regexprops program needs to be a native executable, so we
# can't build it with a cross-compiler.
else
-TESTS += check-regexprops
+TESTS += check-regexprops test_splitstring
endif
libfind_a_SOURCES = findutils-version.c
@@ -32,11 +32,11 @@ MAINTAINERCLEANFILES =
INCLUDES = -I../gl/lib -I$(top_srcdir)/gl/lib
LDADD = ../gl/lib/libgnulib.a $(LIBINTL)
-libfind_a_SOURCES += nextelem.h printquoted.h listfile.h \
- regextype.h dircallback.h safe-atoi.h
-libfind_a_SOURCES += listfile.c nextelem.c extendbuf.c buildcmd.c
savedirinfo.c \
+libfind_a_SOURCES += printquoted.h listfile.h \
+ regextype.h dircallback.h safe-atoi.h splitstring.h
+libfind_a_SOURCES += listfile.c extendbuf.c buildcmd.c savedirinfo.c \
forcefindlib.c qmark.c printquoted.c regextype.c dircallback.c fdleak.c
\
- safe-atoi.c
+ safe-atoi.c splitstring.c
EXTRA_DIST += waitpid.c forcefindlib.c
TESTS_ENVIRONMENT = REGEXPROPS=regexprops$(EXEEXT)
@@ -46,3 +46,5 @@ libfind_a_DEPENDENCIES = $(FINDLIBOBJS)
check-regexprops: check-regexprops.sh
cp $(srcdir)/check-regexprops.sh check-regexprops
chmod +x check-regexprops
+
+test_splitstring_SOURCES = test_splitstring.c splitstring.c
diff --git a/lib/nextelem.c b/lib/nextelem.c
deleted file mode 100644
index 3e9246c..0000000
--- a/lib/nextelem.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Return the next element of a path.
- Copyright (C) 1992, 2005, 2010, 2011 Free Software Foundation, Inc.
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Written by David MacKenzie <address@hidden>,
- inspired by John P. Rouillard <address@hidden>. */
-
-#include <config.h>
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-
-#include "nextelem.h"
-
-
-/* Return the next element of a colon-separated path.
- A null entry in the path is equivalent to "." (the current directory).
-
- If NEW_PATH is non-NULL, set the path and return NULL.
- If NEW_PATH is NULL, return the next item in the string, or
- return NULL if there are no more elements. */
-
-char *
-next_element (const char *new_path, int curdir_ok)
-{
- static char *path = NULL; /* Freshly allocated copy of NEW_PATH. */
- static char *end; /* Start of next element to return. */
- static int final_colon; /* If zero, path didn't end with a colon. */
- char *start; /* Start of path element to return. */
-
- if (new_path)
- {
- free (path);
- end = path = strdup (new_path);
- final_colon = 0;
- return NULL;
- }
-
- if (*end == '\0')
- {
- if (final_colon)
- {
- final_colon = 0;
- return curdir_ok ? "." : "";
- }
- return NULL;
- }
-
- start = end;
- final_colon = 1; /* Maybe there will be one. */
-
- end = strchr (start, ':');
- if (end == start)
- {
- /* An empty path element. */
- *end++ = '\0';
- return curdir_ok ? "." : "";
- }
- else if (end == NULL)
- {
- /* The last path element. */
- end = strchr (start, '\0');
- final_colon = 0;
- }
- else
- *end++ = '\0';
-
- return start;
-}
diff --git a/lib/nextelem.h b/lib/nextelem.h
deleted file mode 100644
index 00ffcfe..0000000
--- a/lib/nextelem.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Return the next element of a path.
- Copyright (C) 1992, 2010, 2011 Free Software Foundation, Inc.
-
- This program 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 of the License, or
- (at your option) any later version.
-
- This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Written by David MacKenzie <address@hidden>,
- inspired by John P. Rouillard <address@hidden>. */
-
-#ifndef INC_NEXTELEM_H
-#define INC_NEXTELEM_H 1
-
-char *next_element (const char *path, int curdir_ok);
-
-#endif
diff --git a/lib/splitstring.c b/lib/splitstring.c
new file mode 100644
index 0000000..e706d9c
--- /dev/null
+++ b/lib/splitstring.c
@@ -0,0 +1,60 @@
+/* splitstring.c -- split a const string into fields.
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ This program 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 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Written by James Youngman.
+ */
+
+#include <config.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "splitstring.h"
+
+static size_t
+field_length (const char *str, const char *separators)
+{
+ /* if there are no separators, the whole input is one field. */
+ if (*separators)
+ {
+ const char *end = strpbrk (str, separators);
+ if (end)
+ return end - str;
+ }
+ return strlen (str);
+}
+
+
+bool
+splitstring(const char *s, const char *separators, bool first,
+ size_t *pos, size_t *len)
+{
+ if (first)
+ {
+ *pos = 0u;
+ *len = 0u;
+ }
+ else
+ {
+ *pos += *len; /* advance to the next field. */
+ if (s[*pos])
+ ++*pos; /* skip the separator */
+ else
+ return false; /* we reached the end. */
+ }
+ *len = field_length (&s[*pos], separators);
+ return true;
+}
diff --git a/lib/splitstring.h b/lib/splitstring.h
new file mode 100644
index 0000000..c91f7e7
--- /dev/null
+++ b/lib/splitstring.h
@@ -0,0 +1,40 @@
+/* splitstring.h -- split a const string into fields.
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ This program 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 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Written by James Youngman.
+ */
+
+/* Split a string into fields. The string is never modified.
+ *
+ * A false return value indicates that there are no more fields.
+ * Otherwise the next field is at the poisition indicated by *POS and
+ * has length *LEN.
+ *
+ * Set FIRST to true only on the first call for any given value of s.
+ * *POS and *LEN do not need to be initialised in this case.
+ * On subsequent calls, these values should be left at the values
+ * set by the last call.
+ *
+ * Any character in SEPARATORS is taken to be a field separator.
+ * Consecutive field separators are taken to indicate the presence of
+ * an empty field.
+ */
+#include <stdbool.h>
+#include <stddef.h>
+
+bool splitstring(const char *s, const char *separators,
+ bool first, size_t *pos, size_t *len);
diff --git a/lib/test_splitstring.c b/lib/test_splitstring.c
new file mode 100644
index 0000000..9dedb7c
--- /dev/null
+++ b/lib/test_splitstring.c
@@ -0,0 +1,201 @@
+/* test_splitstring.c -- unit test for splitstring()
+ Copyright (C) 2011 Free Software Foundation, Inc.
+
+ This program 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 of the License, or
+ (at your option) any later version.
+
+ This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <config.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "splitstring.h"
+
+static void
+assertEqualFunc(const char *file, int line, const char *label,
+ size_t expected, size_t got)
+{
+ if (expected != got)
+ fprintf(stderr, "%s line %d: %s: expected %lu, got %lu\n",
+ file, line, label, (unsigned long)expected, (unsigned long)got);
+}
+#define ASSERT_EQUAL(expected,got) \
+ do{ \
+ assertEqualFunc(__FILE__,__LINE__,"ASSERT_EQUAL",expected,got); \
+ assert (expected == got); \
+ } while (0);
+
+
+static void
+test_empty (void)
+{
+ size_t len, pos;
+ bool result;
+ const char *empty = "";
+
+ result = splitstring (empty, ":", true, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (0, pos);
+ ASSERT_EQUAL (0, len);
+ result = splitstring (empty, ":", false, &pos, &len);
+ assert (!result);
+}
+
+static void test_onefield (void)
+{
+ size_t len, pos;
+ bool result;
+ const char *input = "aaa";
+
+ result = splitstring (input, ":", true, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (0, pos);
+ ASSERT_EQUAL (3, len);
+ result = splitstring (input, ":", false, &pos, &len);
+ assert (!result);
+}
+
+static void test_not_colon (void)
+{
+ size_t len, pos;
+ bool result;
+ const char *separators = "!";
+ const char *input = "aa!b";
+
+ result = splitstring (input, separators, true, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (0, pos);
+ ASSERT_EQUAL (2, len);
+
+ result = splitstring (input, separators, false, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (3, pos);
+ ASSERT_EQUAL (1, len);
+
+ result = splitstring (input, separators, false, &pos, &len);
+ assert (!result);
+}
+
+static void test_empty_back (void)
+{
+ size_t len, pos;
+ bool result;
+ const char *input = "aa:";
+
+ result = splitstring (input, ":", true, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (0, pos);
+ ASSERT_EQUAL (2, len);
+ result = splitstring (input, ":", false, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (3, pos);
+ ASSERT_EQUAL (0, len);
+ result = splitstring (input, ":", false, &pos, &len);
+ assert (!result);
+}
+
+static void test_empty_front (void)
+{
+ size_t len, pos;
+ bool result;
+ const char *input = ":aaa";
+
+ result = splitstring (input, ":", true, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (0, pos);
+ ASSERT_EQUAL (0, len);
+ result = splitstring (input, ":", false, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (1, pos);
+ ASSERT_EQUAL (3, len);
+ result = splitstring (input, ":", false, &pos, &len);
+ assert (!result);
+}
+
+static void test_twofields (void)
+{
+ size_t len, pos;
+ bool result;
+ const char *input = "aaa:bb";
+
+ result = splitstring (input, ":", true, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (0, pos);
+ ASSERT_EQUAL (3, len);
+ result = splitstring (input, ":", false, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (4, pos);
+ ASSERT_EQUAL (2, len);
+ result = splitstring (input, ":", false, &pos, &len);
+ assert (!result);
+}
+
+static void test_twoseparators (void)
+{
+ size_t len, pos;
+ bool result;
+ const char *input = "a:bb!c";
+
+ result = splitstring (input, ":!", true, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (0, pos);
+ ASSERT_EQUAL (1, len);
+ result = splitstring (input, ":!", false, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (2, pos);
+ ASSERT_EQUAL (2, len);
+ result = splitstring (input, ":!", false, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (5, pos);
+ ASSERT_EQUAL (1, len);
+ result = splitstring (input, ":!", false, &pos, &len);
+ assert (!result);
+}
+
+static void test_consecutive_empty (void)
+{
+ size_t len, pos;
+ bool result;
+ const char *input = "a::b";
+ const char *separators = ":";
+
+ result = splitstring (input, separators, true, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (0, pos);
+ ASSERT_EQUAL (1, len);
+
+ result = splitstring (input, separators, false, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (2, pos);
+ ASSERT_EQUAL (0, len);
+
+ result = splitstring (input, separators, false, &pos, &len);
+ assert (result);
+ ASSERT_EQUAL (3, pos);
+ ASSERT_EQUAL (1, len);
+
+ result = splitstring (input, separators, false, &pos, &len);
+ assert (!result);
+}
+
+int main (int argc, char *argv[])
+{
+ test_empty ();
+ test_onefield ();
+ test_not_colon ();
+ test_empty_back ();
+ test_empty_front ();
+ test_twofields ();
+ test_twoseparators ();
+ test_consecutive_empty ();
+ return 0;
+}
diff --git a/locate/locate.c b/locate/locate.c
index ad7b56a..42089ee 100644
--- a/locate/locate.c
+++ b/locate/locate.c
@@ -123,11 +123,11 @@
#include "human.h"
#include "dirname.h"
#include "closeout.h"
-#include "nextelem.h"
#include "regex.h"
#include "quotearg.h"
#include "printquoted.h"
#include "regextype.h"
+#include "splitstring.h"
#include "findutils-version.h"
/* Note that this evaluates Ch many times. */
@@ -1555,7 +1555,11 @@ opendb (const char *name)
int
dolocate (int argc, char **argv, int secure_db_fd)
{
- char *dbpath;
+ char *path_element;
+ size_t path_element_pos, path_element_len;
+ const char *locate_path;
+ const char *db_name;
+ const char *path_separators = ":";
unsigned long int found = 0uL;
int ignore_case = 0;
int print = 0;
@@ -1593,11 +1597,9 @@ dolocate (int argc, char **argv, int secure_db_fd)
* setuid-access-controlled database,, since that could cause a leak
* of private data.
*/
- dbpath = getenv ("LOCATE_PATH");
- if (dbpath)
- {
+ locate_path = getenv ("LOCATE_PATH");
+ if (locate_path)
they_chose_db = 1;
- }
check_existence = ACCEPT_EITHER;
@@ -1629,7 +1631,7 @@ dolocate (int argc, char **argv, int secure_db_fd)
break;
case 'd':
- dbpath = optarg;
+ locate_path = optarg;
they_chose_db = 1;
break;
@@ -1753,7 +1755,8 @@ dolocate (int argc, char **argv, int secure_db_fd)
stdout_is_a_tty = false;
if (they_chose_db)
- next_element (dbpath, 0); /* Initialize. */
+ splitstring (locate_path, path_separators, true,
+ &path_element_pos, &path_element_len);
/* Bail out early if limit already reached. */
while (!use_limit || limits.limit > limits.items_accepted)
@@ -1772,11 +1775,7 @@ dolocate (int argc, char **argv, int secure_db_fd)
if (they_chose_db)
{
/* Take the next element from the list of databases */
- e = next_element ((char *) NULL, 0);
- if (NULL == e)
- break;
-
- if (0 == strcmp (e, "-"))
+ if (1 == path_element_len && '-' == locate_path[path_element_pos])
{
if (did_stdin)
{
@@ -1793,17 +1792,25 @@ dolocate (int argc, char **argv, int secure_db_fd)
}
else
{
- if (0 == strlen (e) || 0 == strcmp (e, "."))
+ if (0 == path_element_len
+ || (1 == path_element_len
+ && '.' == locate_path[path_element_pos]))
+ {
+ db_name = LOCATE_DB;
+ }
+ else
{
- e = LOCATE_DB;
+ path_element = strndup (&locate_path[path_element_pos],
+ path_element_len);
+ db_name = path_element;
}
/* open the database */
- fd = opendb (e);
+ fd = opendb (db_name);
if (fd < 0)
{
error (0, errno, "%s",
- quotearg_n_style (0, locale_quoting_style, e));
+ quotearg_n_style (0, locale_quoting_style, db_name));
return 0;
}
}
@@ -1817,7 +1824,7 @@ dolocate (int argc, char **argv, int secure_db_fd)
}
else
{
- e = selected_secure_db;
+ db_name = selected_secure_db;
fd = secure_db_fd;
secure_db_fd = -1;
}
@@ -1827,7 +1834,7 @@ dolocate (int argc, char **argv, int secure_db_fd)
if (fstat (fd, &st))
{
error (0, errno, "%s",
- quotearg_n_style (0, locale_quoting_style, e));
+ quotearg_n_style (0, locale_quoting_style, db_name));
/* continue anyway */
filesize = (off_t)0;
}
@@ -1855,7 +1862,7 @@ dolocate (int argc, char **argv, int secure_db_fd)
warning: database `fred' is more than 8 days old (actual
age is 10 days)*/
error (0, 0,
_("warning: database %s is more than %d %s old (actual
age is %.1f %s)"),
- quotearg_n_style (0, locale_quoting_style, e),
+ quotearg_n_style (0, locale_quoting_style, db_name),
warn_number_units, _(warn_name_units),
(age/(double)SECONDS_PER_UNIT), _(warn_name_units));
}
@@ -1866,7 +1873,7 @@ dolocate (int argc, char **argv, int secure_db_fd)
if (NULL == fp)
{
error (0, errno, "%s",
- quotearg_n_style (0, locale_quoting_style, e));
+ quotearg_n_style (0, locale_quoting_style, db_name));
return 0;
}
@@ -1881,9 +1888,19 @@ dolocate (int argc, char **argv, int secure_db_fd)
if (fclose (fp) == EOF)
{
error (0, errno, "%s",
- quotearg_n_style (0, locale_quoting_style, e));
+ quotearg_n_style (0, locale_quoting_style, db_name));
return 0;
}
+ if (path_element)
+ {
+ free (path_element);
+ path_element = NULL;
+ }
+ if (!splitstring (locate_path, path_separators, false,
+ &path_element_pos, &path_element_len))
+ {
+ break;
+ }
}
if (just_count)
--
1.7.2.5
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] Split strings into fields nondestructively.,
James Youngman <=