[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[patch] canonicalize_file_name
From: |
Neal H Walfield |
Subject: |
[patch] canonicalize_file_name |
Date: |
Tue, 14 Aug 2001 10:34:55 +0200 |
User-agent: |
Mutt/1.3.18i |
In libparted/device.c, we were using a home brewed hack to canonicalize
a file name (i.e. expand symbolic links, remove superfuous path
components, etc.). This is unnecessary as libc already has the
functionality to do this for us. In a POSIX environment, it is called
realpath. This function, however, has a few problems, namely, it takes
a buffer but no buffer size. Glibc has a function called
canonicalize_file_name which does the same thing as read_path, however,
it does not have the problems associated with read_path.
This patch adds a configure test for canonicalize_file_name and if
found, uses that in libparted/device.c. If, however,
canonicalize_file_name is not found, a wrapper function is present in
libparted/device.c that emulates canonicalize_file_name using
read_path.
As a side node, _POSIX_PATH_MAX should never be used by an application.
POSIX defines this is the minimum accepted value for PATH_MAX. If you
want to use PATH_MAX, you should do so directly. However, POSIX does
not guarantee that PATH_MAX is defined; if it is not, there is no limit.
And, in fact, this is the case on GNU/Hurd.
A change log:
2001-08-12 Neal H Walfield <address@hidden>
* configure.in: Add check for canonicalize_file_name.
* config.h (HAVE_CANONICALIZE_FILE_NAME): New marcro.
* libparted/device.c (_GNU_SOURCE): Enable GNU extensions.
[!HAVE_CANONICALIZE_FILE_NAME] (canonicalize_file_name):
Implement it.
(_readlink): Depreciated and removed in favor of
canonicalize_file_name.
(_strcut): Likewise.
(_remove_doube_slash): Likewise.
(_remove_dots): Likewise.
(_normalize_path): Likewise.
(_ped_device_probe): Use canonicalize_file_name, not
_normalize_path.
(ped_device_get): Likewise.
(devices): Remove superfluous zero initializer.
diff --exclude aclocal.m4 --exclude configure --exclude Makefile.in -urNp
parted-1.5.4-pre1.orig/configure.in parted-1.5.4-pre1/configure.in
--- parted-1.5.4-pre1.orig/configure.in Sun Aug 12 06:38:14 2001
+++ parted-1.5.4-pre1/configure.in Mon Aug 13 17:32:20 2001
@@ -307,6 +307,11 @@ if test x$with_readline = xyes; then
LIBS="$OLD_LIBS"
fi
+OLD_CFLAGS="$CFLAGS"
+CFLAGS=-D_GNU_SOURCE=1
+AC_CHECK_FUNCS(canonicalize_file_name)
+CFLAGS="$OLD_CFLAGS"
+
CFLAGS="$CFLAGS -W -Wall -Wno-unused -Wno-switch -Werror"
AC_OUTPUT([
diff --exclude aclocal.m4 --exclude configure --exclude Makefile.in -urNp
parted-1.5.4-pre1.orig/config.h.in parted-1.5.4-pre1/config.h.in
--- parted-1.5.4-pre1.orig/config.h.in Sun Jul 15 02:47:02 2001
+++ parted-1.5.4-pre1/config.h.in Mon Aug 13 17:32:20 2001
@@ -78,6 +78,9 @@
/* Define if you have the <argz.h> header file. */
#undef HAVE_ARGZ_H
+/* Define if you have the `canonicalize_file_name' function. */
+#undef HAVE_CANONICALIZE_FILE_NAME
+
/* Define if you have the `dcgettext' function. */
#undef HAVE_DCGETTEXT
diff --exclude aclocal.m4 --exclude configure --exclude Makefile.in -urNp
parted-1.5.4-pre1.orig/libparted/device.c parted-1.5.4-pre1/libparted/device.c
--- parted-1.5.4-pre1.orig/libparted/device.c Wed Jul 25 04:11:25 2001
+++ parted-1.5.4-pre1/libparted/device.c Mon Aug 13 18:58:28 2001
@@ -17,6 +17,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define _GNU_SOURCE 1
+
#include "config.h"
#include <parted/parted.h>
@@ -26,7 +28,38 @@
#include <stdlib.h>
#include <unistd.h>
-static PedDevice* devices = NULL;
+static PedDevice* devices;
+
+#ifndef HAVE_CANONICALIZE_FILE_NAME
+char *
+canonicalize_file_name (const char *name)
+{
+ char * buf;
+ int size;
+ char * result;
+
+#ifdef PATH_MAX
+ size = PATH_MAX;
+#else
+ /* Bigger is better; realpath has no way todo bounds checking. */
+ size = 4096;
+#endif
+
+ /* Just in case realpath does not NULL terminate the string
+ * or it just fits in SIZE without a NULL terminator. */
+ buf = calloc (size + 1);
+ if (! buf) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ result = realpath (name, buf);
+ if (! result)
+ free (buf);
+
+ return result;
+}
+#endif /* !HAVE_CANONICALIZE_FILE_NAME */
static void
_device_register (PedDevice* dev)
@@ -65,102 +98,6 @@ ped_device_get_next (const PedDevice* de
return devices;
}
-/* wrap around POSIX brain-damage */
-static int
-_readlink (const char* path, char* buf, size_t size)
-{
- memset (buf, 0, size);
- return readlink (path, buf, size);
-}
-
-static void
-_strcut (char* str, size_t count)
-{
- size_t i;
-
- for (i = count; str [i]; i++)
- str [i - count] = str [i];
- str [i - count] = 0;
-}
-
-static void
-_remove_double_slash (char* path)
-{
- char* match;
-
- while ((match = strstr (path, "//")))
- _strcut (match, 1);
-}
-
-/* removes ./ and XX/../ from path. Obviously broken (will remove a./),
- * but who cares? Expects // to have been removed
- */
-static void
-_remove_dots (char* path)
-{
- char* match;
-
- match = strchr (path, '.');
- while (match) {
- if (!strncmp (match, "./", 2)) {
- _strcut (match, 2);
- } else if (!strncmp (match, "../", 3)) {
- char* cut_start;
-
- for (cut_start = match - 2;
- *cut_start != '/'; cut_start--) {
- if (cut_start < path)
- return; /* broken path! */
- }
-
- _strcut (cut_start, match - cut_start + 2);
- }
-
- match = strchr (path, '.');
- }
-}
-
-/* follows symbolic links. WTF isn't this in libc?! */
-static char*
-_normalize_path (const char* path)
-{
- char normalized [_POSIX_PATH_MAX + 1];
- int normalized_len;
- char tmp [_POSIX_PATH_MAX + 1];
-
- strcpy (normalized, path);
- _remove_double_slash (normalized);
- _remove_dots (normalized);
- normalized_len = strlen (path);
-
- while (_readlink (normalized, tmp, _POSIX_PATH_MAX + 1) > 0) {
- if (tmp [0] == '/') {
- strcpy (normalized, tmp);
- } else {
- char* slash_match = strrchr (normalized, '/');
- char* cpy_loc;
-
- if (slash_match) {
- if (slash_match - normalized + normalized_len
- > _POSIX_PATH_MAX)
- return NULL;
- cpy_loc = slash_match + 1;
- } else {
- cpy_loc = normalized;
- }
-
- /* check for recursive sym-links */
- if (!strcmp (cpy_loc, tmp))
- return NULL;
- strcpy (cpy_loc, tmp);
- }
- _remove_double_slash (normalized);
- _remove_dots (normalized);
- normalized_len = strlen (path);
- }
- return strdup (normalized);
-}
-
void
_ped_device_probe (const char* path)
{
@@ -168,7 +105,11 @@ _ped_device_probe (const char* path)
PedDevice* dev;
PED_ASSERT (path != NULL, return);
- normalized_path = _normalize_path (path);
+ normalized_path = canonicalize_file_name (path);
+ if (!normalized_path)
+ /* Well, maybe it is just that the file does not exist.
+ * Try it anyway. */
+ normalized_path = strdup (path);
if (!normalized_path)
return;
@@ -206,7 +147,11 @@ ped_device_get (const char* path)
char* normal_path;
PED_ASSERT (path != NULL, return NULL);
- normal_path = _normalize_path (path);
+ normal_path = canonicalize_file_name (path);
+ if (!normal_path)
+ /* Well, maybe it is just that the file does not exist.
+ * Try it anyway. */
+ normal_path = strdup (path);
if (!normal_path)
return NULL;
pgpkcN_I6XJ4b.pgp
Description: PGP signature
- [patch] canonicalize_file_name,
Neal H Walfield <=