summaryrefslogtreecommitdiff
path: root/src/shared/udev-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/udev-util.c')
-rw-r--r--src/shared/udev-util.c45
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;
+}