]> git.ipfire.org Git - thirdparty/util-linux.git/blame - lib/mangle.c
taskset: Accept 0 pid for current process
[thirdparty/util-linux.git] / lib / mangle.c
CommitLineData
21169393
KZ
1/*
2 * Functions for \oct encoding used in mtab/fstab/swaps/etc.
3 *
40f8c5e4
KZ
4 * No copyright is claimed. This code is in the public domain; do with
5 * it what you wish.
21169393 6 *
44da1cb1 7 * Written by Karel Zak <kzak@redhat.com> [2010]
21169393
KZ
8 */
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <ctype.h>
13
14#include "mangle.h"
eb76ca98 15#include "c.h"
21169393 16
95387b66
KZ
17#define isoctal(a) (((a) & ~7) == '0')
18
19#define from_hex(c) (isdigit(c) ? c - '0' : tolower(c) - 'a' + 10)
20
21#define is_unwanted_char(x) (strchr(" \t\n\\", (unsigned int) x) != NULL)
21169393 22
21169393
KZ
23
24char *mangle(const char *s)
25{
26 char *ss, *sp;
21169393 27
7a539b29
KZ
28 if (!s)
29 return NULL;
30
95387b66 31 ss = sp = malloc(4 * strlen(s) + 1);
21169393
KZ
32 if (!sp)
33 return NULL;
34 while(1) {
ea178007
DR
35 if (!*s) {
36 *sp = '\0';
37 break;
38 }
95387b66
KZ
39 if (is_unwanted_char(*s)) {
40 *sp++ = '\\';
41 *sp++ = '0' + ((*s & 0300) >> 6);
42 *sp++ = '0' + ((*s & 070) >> 3);
43 *sp++ = '0' + (*s & 07);
ea178007 44 } else
95387b66 45 *sp++ = *s;
21169393
KZ
46 s++;
47 }
48 return ss;
49}
50
95387b66 51
3c5e4ef8 52void unmangle_to_buffer(const char *s, char *buf, size_t len)
21169393
KZ
53{
54 size_t sz = 0;
55
7a539b29
KZ
56 if (!s)
57 return;
58
21169393 59 while(*s && sz < len - 1) {
096db1ea 60 if (*s == '\\' && sz + 3 < len - 1 && isoctal(s[1]) &&
21169393
KZ
61 isoctal(s[2]) && isoctal(s[3])) {
62
63 *buf++ = 64*(s[1] & 7) + 8*(s[2] & 7) + (s[3] & 7);
64 s += 4;
65 sz += 4;
66 } else {
67 *buf++ = *s++;
68 sz++;
69 }
70 }
71 *buf = '\0';
72}
73
61b92339 74size_t unhexmangle_to_buffer(const char *s, char *buf, size_t len)
95387b66
KZ
75{
76 size_t sz = 0;
61b92339 77 const char *buf0 = buf;
95387b66
KZ
78
79 if (!s)
61b92339 80 return 0;
95387b66
KZ
81
82 while(*s && sz < len - 1) {
096db1ea 83 if (*s == '\\' && sz + 3 < len - 1 && s[1] == 'x' &&
95387b66
KZ
84 isxdigit(s[2]) && isxdigit(s[3])) {
85
86 *buf++ = from_hex(s[2]) << 4 | from_hex(s[3]);
87 s += 4;
88 sz += 4;
89 } else {
90 *buf++ = *s++;
91 sz++;
92 }
93 }
94 *buf = '\0';
61b92339 95 return buf - buf0 + 1;
95387b66
KZ
96}
97
00e70d30
KZ
98size_t unescape_to_buffer(const char *s, const char *wanted, char *buf, size_t len)
99{
100 size_t sz = 0;
101 const char *buf0 = buf;
102
103 while (*s && sz < len - 1) {
104 if (*s == '\\' && sz + 1 < len - 1 && strchr(wanted, s[1])) {
105 *buf++ = s[1];
106 s += 2;
107 sz += 2;
108 } else {
109 *buf++ = *s++;;
110 sz++;
111 }
112 }
113 *buf = '\0';
114 return buf - buf0 + 1;
115}
116
78c66fc6 117static inline const char *skip_nonspaces(const char *s)
21169393 118{
36fcefa6 119 while (s && *s && !(*s == ' ' || *s == '\t'))
21169393 120 s++;
78c66fc6 121 return s;
21169393
KZ
122}
123
124/*
125 * Returns mallocated buffer or NULL in case of error.
126 */
78c66fc6 127char *unmangle(const char *s, const char **end)
21169393 128{
3c5e4ef8 129 char *buf;
78c66fc6 130 const char *e;
21169393
KZ
131 size_t sz;
132
7a539b29
KZ
133 if (!s)
134 return NULL;
135
dd369652
KZ
136 e = skip_nonspaces(s);
137 sz = e - s + 1;
138
139 if (end)
140 *end = e;
6c7f688b
KZ
141 if (e == s)
142 return NULL; /* empty string */
21169393
KZ
143
144 buf = malloc(sz);
145 if (!buf)
146 return NULL;
147
148 unmangle_to_buffer(s, buf, sz);
149 return buf;
150}
151
e8f7acb0 152#ifdef TEST_PROGRAM_MANGLE
21169393
KZ
153#include <errno.h>
154int main(int argc, char *argv[])
155{
a0b25068 156 char *p = NULL;
21169393 157 if (argc < 3) {
00e70d30 158 fprintf(stderr, "usage: %s --mangle|unmangle|unescape <string>\n",
21169393
KZ
159 program_invocation_short_name);
160 return EXIT_FAILURE;
161 }
162
a0b25068
CW
163 if (!strcmp(argv[1], "--mangle")) {
164 p = mangle(argv[2]);
165 printf("mangled: '%s'\n", p);
166 free(p);
167 }
21169393
KZ
168
169 else if (!strcmp(argv[1], "--unmangle")) {
dd369652 170 char *x = unmangle(argv[2], NULL);
8f3f6383
KZ
171
172 if (x) {
21169393 173 printf("unmangled: '%s'\n", x);
8f3f6383
KZ
174 free(x);
175 }
176
177 x = strdup(argv[2]);
8f3f6383 178 if (x) {
4f807791
SK
179 unmangle_to_buffer(x, x, strlen(x) + 1);
180
8f3f6383
KZ
181 printf("self-unmangled: '%s'\n", x);
182 free(x);
183 }
21169393
KZ
184 }
185
00e70d30
KZ
186 else if (!strcmp(argv[1], "--unescape")) {
187 char *x = strdup(argv[2]);
188 if (x) {
189 unescape_to_buffer(x, ",\"", x, strlen(x) + 1);
190
191 printf("self-unescaped: '%s'\n", x);
192 free(x);
193 }
194 }
195
21169393
KZ
196 return EXIT_SUCCESS;
197}
e8f7acb0 198#endif /* TEST_PROGRAM_MANGLE */