Base64 en/decode a string and '/' in standard base64 is replaced with
'_',
so that encoded string can be safely used as a filesystem path component;
* src/util/util.c: implementation
* src/util/util.h: declaration
* src/libvirt_private.syms: private symbols
Signed-off-by: Hong Xiang <hxiang(a)linux.vnet.ibm.com>
---
src/libvirt_private.syms | 2 +
src/util/util.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/util.h | 4 ++
3 files changed, 79 insertions(+), 0 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4ae1157..5299f79 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1082,6 +1082,8 @@ safewrite;
safezero;
virArgvToString;
virAsprintf;
+virBase64EncodePathname;
+virBase64DecodePathname;
virBuildPathInternal;
virDirCreate;
virEmitXMLWarning;
diff --git a/src/util/util.c b/src/util/util.c
index af27344..3aa6f2e 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -67,6 +67,7 @@
#include "dirname.h"
#include "virterror_internal.h"
+#include "base64.h"
#include "logging.h"
#include "buf.h"
#include "util.h"
@@ -2497,3 +2498,75 @@ or other application using the libvirt API.\n\
return 0;
}
+
+/**
+ * virBase64EncodePath:
+ * @src: source
+ * @dst: pointer to result
+ *
+ * Base64-encode @src, put pointer to dynamically allocated result into
+ * @dst.
+ * *And* make the result a filesystem safe pathname by replacing all '/'
+ * therein with '_'.
+ *
+ * Return 0 on success and -1 on failure.
+ */
+int
+virBase64EncodePathname(const char * src, char ** dst)
+{
+ char *ptr;
+
+ base64_encode_alloc(src, strlen(src), dst);
+ if(NULL == *dst)
+ return -1;
+ for (ptr = *dst; *ptr; ptr ++) {
+ if('/' == *ptr)
+ *ptr = '_';
+ }
+ return 0;
+}
+
+/**
+ * virBase64Decode:
+ * @src: source
+ * @dst: pointer to result
+ *
+ * Convert @src to a standard base64 string by replacing all '_' with
'/',
+ * then base64-decode the intermediate result; pointer to dynamically
+ * allocated final result is put in @dst.
+ *
+ * Return 0 on success and -1 on memory failure and -2 if @src does not
+ * contain a valid base64 encoded string.
+ */
+int
+virBase64DecodePathname(const char * src, char ** dst)
+{
+ char *i_dst;
+ int i;
+ size_t dst_len;
+
+ *dst = NULL;
+ if(VIR_ALLOC_N(i_dst, strlen(src)) < 0)
+ return -1;
+ for (i = 0; src[i]; i ++) {
+ if('_' == src[i])
+ i_dst[i] = '/';
+ else
+ i_dst[i] = src[i];
+ }
+
+ dst_len = 3 * (i / 4) + 4;
+ if(VIR_ALLOC_N(*dst, dst_len) < 0) {
+ VIR_FREE(i_dst);
+ return -1;
+ }
+ if(!base64_decode_ctx(NULL, i_dst, i, *dst, &dst_len)) {
+ VIR_FREE(i_dst);
+ VIR_FREE(*dst);
+ return -2;
+ }
+ VIR_FREE(i_dst);
+ (*dst)[dst_len] = '\0';
+
+ return 0;
+}
diff --git a/src/util/util.h b/src/util/util.h
index c55e852..7fb41c2 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -260,4 +260,8 @@ bool virIsDevMapperDevice(const char *dev_name) ATTRIBUTE_NONNULL(1);
int virEmitXMLWarning(int fd,
const char *name,
const char *cmd) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
+
+int virBase64EncodePathname(const char * src, char ** dst);
+int virBase64DecodePathname(const char * src, char ** dst);
+
#endif /* __VIR_UTIL_H__ */
--
1.7.1