Introduce a new helper function to resolve a path name, calling
nbdkit_error on failure: other than doing what nbdkit_absolute_path
does, it also checks that the file exists (and thus avoids errors later
on).  To help distinguish it from nbdkit_absolute_path, improve the
documentation of the latter.

Apply it where an existing path is required, both in nbdkit itself and
in plugins.

Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1527334
---
 docs/nbdkit-plugin.pod      | 18 +++++++++++++++++-
 include/nbdkit-common.h     |  1 +
 plugins/example2/example2.c |  2 +-
 plugins/file/file.c         |  6 +-----
 plugins/gzip/gzip.c         |  2 +-
 plugins/split/split.c       |  2 +-
 plugins/vddk/vddk.c         |  2 +-
 plugins/xz/xz.c             |  2 +-
 src/plugins.c               |  2 +-
 src/utils.c                 | 19 +++++++++++++++++++
 10 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/docs/nbdkit-plugin.pod b/docs/nbdkit-plugin.pod
index 44822fc..5faba1d 100644
--- a/docs/nbdkit-plugin.pod
+++ b/docs/nbdkit-plugin.pod
@@ -200,13 +200,29 @@ descriptor.
  char *nbdkit_absolute_path (const char *filename);
 
 The utility function C<nbdkit_absolute_path> converts any path to an
-absolute path.
+absolute path: if it is relative, then all this function does is
+prepending the current working directory to the path, with no extra
+checks.
 
 If conversion was not possible, this calls C<nbdkit_error> and returns
 C<NULL>.  Note that this function does not check that the file exists.
 
 The returned string must be freed by the caller.
 
+=head2 C<nbdkit_realpath>
+
+ char *nbdkit_realpath (const char *filename);
+
+The utility function C<nbdkit_realpath> converts any path to an
+absolute path, resolving symlinks.  Under the hood it uses the
+C<realpath> function, and thus it fails if the path does not exist,
+or it is not possible to access to any of the components of the path.
+
+If the path resolution was not possible, this calls C<nbdkit_error>
+and returns C<NULL>.
+
+The returned string must be freed by the caller.
+
 =head1 CALLBACKS
 
 =head2 C<.name>
diff --git a/include/nbdkit-common.h b/include/nbdkit-common.h
index 5e69579..693213f 100644
--- a/include/nbdkit-common.h
+++ b/include/nbdkit-common.h
@@ -60,6 +60,7 @@ extern void nbdkit_vdebug (const char *msg, va_list args);
 extern char *nbdkit_absolute_path (const char *path);
 extern int64_t nbdkit_parse_size (const char *str);
 extern int nbdkit_read_password (const char *value, char **password);
+extern char *nbdkit_realpath (const char *path);
 
 #ifdef __cplusplus
 }
diff --git a/plugins/example2/example2.c b/plugins/example2/example2.c
index 5bc4f94..a2d6fca 100644
--- a/plugins/example2/example2.c
+++ b/plugins/example2/example2.c
@@ -78,7 +78,7 @@ example2_config (const char *key, const char *value)
 {
   if (strcmp (key, "file") == 0) {
     /* See FILENAMES AND PATHS in nbdkit-plugin(3). */
-    filename = nbdkit_absolute_path (value);
+    filename = nbdkit_realpath (value);
     if (!filename)
       return -1;
   }
diff --git a/plugins/file/file.c b/plugins/file/file.c
index f8cb3d3..b6e33de 100644
--- a/plugins/file/file.c
+++ b/plugins/file/file.c
@@ -65,7 +65,7 @@ file_config (const char *key, const char *value)
   if (strcmp (key, "file") == 0) {
     /* See FILENAMES AND PATHS in nbdkit-plugin(3). */
     free (filename);
-    filename = nbdkit_absolute_path (value);
+    filename = nbdkit_realpath (value);
     if (!filename)
       return -1;
   }
@@ -90,10 +90,6 @@ file_config_complete (void)
     nbdkit_error ("you must supply the file=<FILENAME> parameter after the 
plugin name on the command line");
     return -1;
   }
-  if (access (filename, F_OK) < 0) {
-    nbdkit_error ("access '%s': %m", filename);
-    return -1;
-  }
 
   return 0;
 }
diff --git a/plugins/gzip/gzip.c b/plugins/gzip/gzip.c
index e9dbfdb..09dd629 100644
--- a/plugins/gzip/gzip.c
+++ b/plugins/gzip/gzip.c
@@ -62,7 +62,7 @@ gzip_config (const char *key, const char *value)
 {
   if (strcmp (key, "file") == 0) {
     /* See FILENAMES AND PATHS in nbdkit-plugin(3). */
-    filename = nbdkit_absolute_path (value);
+    filename = nbdkit_realpath (value);
     if (!filename)
       return -1;
   }
diff --git a/plugins/split/split.c b/plugins/split/split.c
index 47c366d..bdcdcf7 100644
--- a/plugins/split/split.c
+++ b/plugins/split/split.c
@@ -76,7 +76,7 @@ split_config (const char *key, const char *value)
       return -1;
     }
     filenames = new_filenames;
-    filenames[nr_files] = nbdkit_absolute_path (value);
+    filenames[nr_files] = nbdkit_realpath (value);
     if (filenames[nr_files] == NULL)
       return -1;
     nr_files++;
diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c
index 1c15127..8bc1517 100644
--- a/plugins/vddk/vddk.c
+++ b/plugins/vddk/vddk.c
@@ -153,7 +153,7 @@ vddk_config (const char *key, const char *value)
   if (strcmp (key, "config") == 0) {
     /* See FILENAMES AND PATHS in nbdkit-plugin(3). */
     free (config);
-    config = nbdkit_absolute_path (value);
+    config = nbdkit_realpath (value);
     if (!config)
       return -1;
   }
diff --git a/plugins/xz/xz.c b/plugins/xz/xz.c
index 437f798..f45e489 100644
--- a/plugins/xz/xz.c
+++ b/plugins/xz/xz.c
@@ -67,7 +67,7 @@ xz_config (const char *key, const char *value)
 {
   if (strcmp (key, "file") == 0) {
     /* See FILENAMES AND PATHS in nbdkit-plugin(3). */
-    filename = nbdkit_absolute_path (value);
+    filename = nbdkit_realpath (value);
     if (!filename)
       return -1;
   }
diff --git a/src/plugins.c b/src/plugins.c
index dba3e24..595b632 100644
--- a/src/plugins.c
+++ b/src/plugins.c
@@ -134,7 +134,7 @@ plugin_dump_fields (struct backend *b)
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
   char *path;
 
-  path = nbdkit_absolute_path (p->filename);
+  path = nbdkit_realpath (p->filename);
   printf ("path=%s\n", path);
   free (path);
 
diff --git a/src/utils.c b/src/utils.c
index 0083370..c6c8003 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -228,3 +228,22 @@ nbdkit_read_password (const char *value, char **password)
 
   return 0;
 }
+
+char *
+nbdkit_realpath (const char *path)
+{
+  char *ret;
+
+  if (path == NULL || *path == '\0') {
+    nbdkit_error ("cannot resolve a null or empty path");
+    return NULL;
+  }
+
+  ret = realpath (path, NULL);
+  if (ret == NULL) {
+    nbdkit_error ("realpath(%s): %m", path);
+    return NULL;
+  }
+
+  return ret;
+}
-- 
2.14.3

_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://www.redhat.com/mailman/listinfo/libguestfs

Reply via email to