2 * Functions for \oct encoding used in mtab/fstab/swaps/etc.
4 * No copyright is claimed. This code is in the public domain; do with
7 * Copyright (C) 2010 Karel Zak <kzak@redhat.com>
17 #define isoctal(a) (((a) & ~7) == '0')
19 #define from_hex(c) (isdigit(c) ? c - '0' : tolower(c) - 'a' + 10)
21 #define is_unwanted_char(x) (strchr(" \t\n\\", (unsigned int) x) != NULL)
24 char *mangle(const char *s
)
31 ss
= sp
= malloc(4 * strlen(s
) + 1);
39 if (is_unwanted_char(*s
)) {
41 *sp
++ = '0' + ((*s
& 0300) >> 6);
42 *sp
++ = '0' + ((*s
& 070) >> 3);
43 *sp
++ = '0' + (*s
& 07);
52 void unmangle_to_buffer(const char *s
, char *buf
, size_t len
)
59 while(*s
&& sz
< len
- 1) {
60 if (*s
== '\\' && sz
+ 3 < len
- 1 && isoctal(s
[1]) &&
61 isoctal(s
[2]) && isoctal(s
[3])) {
63 *buf
++ = 64*(s
[1] & 7) + 8*(s
[2] & 7) + (s
[3] & 7);
74 size_t unhexmangle_to_buffer(const char *s
, char *buf
, size_t len
)
77 const char *buf0
= buf
;
82 while(*s
&& sz
< len
- 1) {
83 if (*s
== '\\' && sz
+ 3 < len
- 1 && s
[1] == 'x' &&
84 isxdigit(s
[2]) && isxdigit(s
[3])) {
86 *buf
++ = from_hex(s
[2]) << 4 | from_hex(s
[3]);
95 return buf
- buf0
+ 1;
98 static inline const char *skip_nonspaces(const char *s
)
100 while (s
&& *s
&& !(*s
== ' ' || *s
== '\t'))
106 * Returns mallocated buffer or NULL in case of error.
108 char *unmangle(const char *s
, const char **end
)
117 e
= skip_nonspaces(s
);
123 return NULL
; /* empty string */
129 unmangle_to_buffer(s
, buf
, sz
);
133 #ifdef TEST_PROGRAM_MANGLE
135 int main(int argc
, char *argv
[])
139 fprintf(stderr
, "usage: %s --mangle|unmangle <string>\n",
140 program_invocation_short_name
);
144 if (!strcmp(argv
[1], "--mangle")) {
146 printf("mangled: '%s'\n", p
);
150 else if (!strcmp(argv
[1], "--unmangle")) {
151 char *x
= unmangle(argv
[2], NULL
);
154 printf("unmangled: '%s'\n", x
);
160 unmangle_to_buffer(x
, x
, strlen(x
) + 1);
162 printf("self-unmangled: '%s'\n", x
);
169 #endif /* TEST_PROGRAM_MANGLE */