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@xxxxxxxxxxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list