diff options
Diffstat (limited to 'src/shared/udev-util.c')
-rw-r--r-- | src/shared/udev-util.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c index 17b9ed137b..d03e4bbe6f 100644 --- a/src/shared/udev-util.c +++ b/src/shared/udev-util.c @@ -5,6 +5,7 @@ #include <unistd.h> #include "alloc-util.h" +#include "device-nodes.h" #include "device-util.h" #include "env-file.h" #include "escape.h" @@ -426,3 +427,47 @@ size_t udev_replace_whitespace(const char *str, char *to, size_t len) { to[j] = '\0'; return j; } + +size_t udev_replace_chars(char *str, const char *allow) { + size_t i = 0, replaced = 0; + + assert(str); + + /* allow chars in allow list, plain ascii, hex-escaping and valid utf8. */ + + while (str[i] != '\0') { + int len; + + if (allow_listed_char_for_devnode(str[i], allow)) { + i++; + continue; + } + + /* accept hex encoding */ + if (str[i] == '\\' && str[i+1] == 'x') { + i += 2; + continue; + } + + /* accept valid utf8 */ + len = utf8_encoded_valid_unichar(str + i, (size_t) -1); + if (len > 1) { + i += len; + continue; + } + + /* if space is allowed, replace whitespace with ordinary space */ + if (isspace(str[i]) && allow && strchr(allow, ' ')) { + str[i] = ' '; + i++; + replaced++; + continue; + } + + /* everything else is replaced with '_' */ + str[i] = '_'; + i++; + replaced++; + } + return replaced; +} |