X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=util.c;h=6ed87a76262827cbb0e74cfbe370cb3736ae003e;hp=4847310aee57d084d5009c0cf0132002ee260e8b;hb=ea4309869e75497ba6a97c540646cb66a157a4d9;hpb=b9f880f4f4903f5dd8198fc1e2e920a9850ac86e;ds=sidebyside diff --git a/util.c b/util.c index 4847310ae..6ed87a762 100644 --- a/util.c +++ b/util.c @@ -566,10 +566,10 @@ int unhexchar(char c) { return c - '0'; if (c >= 'a' && c <= 'f') - return c - 'a'; + return c - 'a' + 10; if (c >= 'A' && c <= 'F') - return c - 'A'; + return c - 'A' + 10; return -1; } @@ -803,6 +803,66 @@ char *xescape(const char *s, const char *bad) { return r; } +char *bus_path_escape(const char *s) { + assert(s); + + char *r, *t; + const char *f; + + /* Escapes all chars that D-Bus' object path cannot deal + * with. Can be reverse with bus_path_unescape() */ + + if (!(r = new(char, strlen(s)*3+1))) + return NULL; + + for (f = s, t = r; *f; f++) { + + if (!(*f >= 'A' && *f <= 'Z') && + !(*f >= 'a' && *f <= 'z') && + !(*f >= '0' && *f <= '9')) { + *(t++) = '_'; + *(t++) = hexchar(*f >> 4); + *(t++) = hexchar(*f); + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + +char *bus_path_unescape(const char *s) { + assert(s); + + char *r, *t; + const char *f; + + if (!(r = new(char, strlen(s)+1))) + return NULL; + + for (f = s, t = r; *f; f++) { + + if (*f == '_') { + int a, b; + + if ((a = unhexchar(f[1])) < 0 || + (b = unhexchar(f[2])) < 0) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '_'; + } else { + *(t++) = (char) ((a << 4) | b); + f += 2; + } + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + char *path_kill_slashes(char *path) { char *f, *t; bool slash = false;