string_helpers: add kstrdup_quotable_cmdline
[linux-2.6-block.git] / lib / string_helpers.c
CommitLineData
3c9f3681
JB
1/*
2 * Helpers for formatting and printing strings
3 *
4 * Copyright 31 August 2008 James Bottomley
16c7fa05 5 * Copyright (C) 2013, Intel Corporation
3c9f3681 6 */
b9f28d86 7#include <linux/bug.h>
3c9f3681
JB
8#include <linux/kernel.h>
9#include <linux/math64.h>
8bc3bcc9 10#include <linux/export.h>
16c7fa05 11#include <linux/ctype.h>
c8250381 12#include <linux/errno.h>
0d044328 13#include <linux/mm.h>
b53f27e4 14#include <linux/slab.h>
c8250381 15#include <linux/string.h>
3c9f3681
JB
16#include <linux/string_helpers.h>
17
18/**
19 * string_get_size - get the size in the specified units
b9f28d86
JB
20 * @size: The size to be converted in blocks
21 * @blk_size: Size of the block (use 1 for size in bytes)
3c9f3681
JB
22 * @units: units to use (powers of 1000 or 1024)
23 * @buf: buffer to format to
24 * @len: length of buffer
25 *
26 * This function returns a string formatted to 3 significant figures
d1214c65
RV
27 * giving the size in the required units. @buf should have room for
28 * at least 9 bytes and will always be zero terminated.
3c9f3681
JB
29 *
30 */
b9f28d86 31void string_get_size(u64 size, u64 blk_size, const enum string_size_units units,
d1214c65 32 char *buf, int len)
3c9f3681 33{
142cda5d 34 static const char *const units_10[] = {
b9f28d86 35 "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"
142cda5d
MK
36 };
37 static const char *const units_2[] = {
b9f28d86 38 "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"
142cda5d
MK
39 };
40 static const char *const *const units_str[] = {
41 [STRING_UNITS_10] = units_10,
3c9f3681
JB
42 [STRING_UNITS_2] = units_2,
43 };
68aecfb9 44 static const unsigned int divisor[] = {
3c9f3681
JB
45 [STRING_UNITS_10] = 1000,
46 [STRING_UNITS_2] = 1024,
47 };
564b026f
JB
48 static const unsigned int rounding[] = { 500, 50, 5 };
49 int i = 0, j;
50 u32 remainder = 0, sf_cap;
3c9f3681 51 char tmp[8];
b9f28d86 52 const char *unit;
3c9f3681
JB
53
54 tmp[0] = '\0';
564b026f
JB
55
56 if (blk_size == 0)
57 size = 0;
58 if (size == 0)
b9f28d86 59 goto out;
3c9f3681 60
564b026f
JB
61 /* This is Napier's algorithm. Reduce the original block size to
62 *
63 * coefficient * divisor[units]^i
64 *
65 * we do the reduction so both coefficients are just under 32 bits so
66 * that multiplying them together won't overflow 64 bits and we keep
67 * as much precision as possible in the numbers.
68 *
69 * Note: it's safe to throw away the remainders here because all the
70 * precision is in the coefficients.
71 */
72 while (blk_size >> 32) {
73 do_div(blk_size, divisor[units]);
b9f28d86
JB
74 i++;
75 }
76
564b026f
JB
77 while (size >> 32) {
78 do_div(size, divisor[units]);
b9f28d86 79 i++;
b9f28d86
JB
80 }
81
564b026f
JB
82 /* now perform the actual multiplication keeping i as the sum of the
83 * two logarithms */
b9f28d86 84 size *= blk_size;
3c9f3681 85
564b026f 86 /* and logarithmically reduce it until it's just under the divisor */
b9f28d86
JB
87 while (size >= divisor[units]) {
88 remainder = do_div(size, divisor[units]);
89 i++;
3c9f3681
JB
90 }
91
564b026f
JB
92 /* work out in j how many digits of precision we need from the
93 * remainder */
b9f28d86
JB
94 sf_cap = size;
95 for (j = 0; sf_cap*10 < 1000; j++)
96 sf_cap *= 10;
97
564b026f
JB
98 if (units == STRING_UNITS_2) {
99 /* express the remainder as a decimal. It's currently the
100 * numerator of a fraction whose denominator is
101 * divisor[units], which is 1 << 10 for STRING_UNITS_2 */
b9f28d86 102 remainder *= 1000;
564b026f
JB
103 remainder >>= 10;
104 }
105
106 /* add a 5 to the digit below what will be printed to ensure
107 * an arithmetical round up and carry it through to size */
108 remainder += rounding[j];
109 if (remainder >= 1000) {
110 remainder -= 1000;
111 size += 1;
112 }
113
114 if (j) {
b9f28d86
JB
115 snprintf(tmp, sizeof(tmp), ".%03u", remainder);
116 tmp[j+1] = '\0';
117 }
118
119 out:
120 if (i >= ARRAY_SIZE(units_2))
121 unit = "UNK";
122 else
123 unit = units_str[units][i];
124
84b9fbed 125 snprintf(buf, len, "%u%s %s", (u32)size,
b9f28d86 126 tmp, unit);
3c9f3681
JB
127}
128EXPORT_SYMBOL(string_get_size);
16c7fa05
AS
129
130static bool unescape_space(char **src, char **dst)
131{
132 char *p = *dst, *q = *src;
133
134 switch (*q) {
135 case 'n':
136 *p = '\n';
137 break;
138 case 'r':
139 *p = '\r';
140 break;
141 case 't':
142 *p = '\t';
143 break;
144 case 'v':
145 *p = '\v';
146 break;
147 case 'f':
148 *p = '\f';
149 break;
150 default:
151 return false;
152 }
153 *dst += 1;
154 *src += 1;
155 return true;
156}
157
158static bool unescape_octal(char **src, char **dst)
159{
160 char *p = *dst, *q = *src;
161 u8 num;
162
163 if (isodigit(*q) == 0)
164 return false;
165
166 num = (*q++) & 7;
167 while (num < 32 && isodigit(*q) && (q - *src < 3)) {
168 num <<= 3;
169 num += (*q++) & 7;
170 }
171 *p = num;
172 *dst += 1;
173 *src = q;
174 return true;
175}
176
177static bool unescape_hex(char **src, char **dst)
178{
179 char *p = *dst, *q = *src;
180 int digit;
181 u8 num;
182
183 if (*q++ != 'x')
184 return false;
185
186 num = digit = hex_to_bin(*q++);
187 if (digit < 0)
188 return false;
189
190 digit = hex_to_bin(*q);
191 if (digit >= 0) {
192 q++;
193 num = (num << 4) | digit;
194 }
195 *p = num;
196 *dst += 1;
197 *src = q;
198 return true;
199}
200
201static bool unescape_special(char **src, char **dst)
202{
203 char *p = *dst, *q = *src;
204
205 switch (*q) {
206 case '\"':
207 *p = '\"';
208 break;
209 case '\\':
210 *p = '\\';
211 break;
212 case 'a':
213 *p = '\a';
214 break;
215 case 'e':
216 *p = '\e';
217 break;
218 default:
219 return false;
220 }
221 *dst += 1;
222 *src += 1;
223 return true;
224}
225
d295634e
AS
226/**
227 * string_unescape - unquote characters in the given string
228 * @src: source buffer (escaped)
229 * @dst: destination buffer (unescaped)
230 * @size: size of the destination buffer (0 to unlimit)
231 * @flags: combination of the flags (bitwise OR):
232 * %UNESCAPE_SPACE:
233 * '\f' - form feed
234 * '\n' - new line
235 * '\r' - carriage return
236 * '\t' - horizontal tab
237 * '\v' - vertical tab
238 * %UNESCAPE_OCTAL:
239 * '\NNN' - byte with octal value NNN (1 to 3 digits)
240 * %UNESCAPE_HEX:
241 * '\xHH' - byte with hexadecimal value HH (1 to 2 digits)
242 * %UNESCAPE_SPECIAL:
243 * '\"' - double quote
244 * '\\' - backslash
245 * '\a' - alert (BEL)
246 * '\e' - escape
247 * %UNESCAPE_ANY:
248 * all previous together
249 *
250 * Description:
251 * The function unquotes characters in the given string.
252 *
253 * Because the size of the output will be the same as or less than the size of
254 * the input, the transformation may be performed in place.
255 *
256 * Caller must provide valid source and destination pointers. Be aware that
257 * destination buffer will always be NULL-terminated. Source string must be
258 * NULL-terminated as well.
259 *
260 * Return:
261 * The amount of the characters processed to the destination buffer excluding
262 * trailing '\0' is returned.
263 */
16c7fa05
AS
264int string_unescape(char *src, char *dst, size_t size, unsigned int flags)
265{
266 char *out = dst;
267
268 while (*src && --size) {
269 if (src[0] == '\\' && src[1] != '\0' && size > 1) {
270 src++;
271 size--;
272
273 if (flags & UNESCAPE_SPACE &&
274 unescape_space(&src, &out))
275 continue;
276
277 if (flags & UNESCAPE_OCTAL &&
278 unescape_octal(&src, &out))
279 continue;
280
281 if (flags & UNESCAPE_HEX &&
282 unescape_hex(&src, &out))
283 continue;
284
285 if (flags & UNESCAPE_SPECIAL &&
286 unescape_special(&src, &out))
287 continue;
288
289 *out++ = '\\';
290 }
291 *out++ = *src++;
292 }
293 *out = '\0';
294
295 return out - dst;
296}
297EXPORT_SYMBOL(string_unescape);
c8250381 298
3aeddc7d 299static bool escape_passthrough(unsigned char c, char **dst, char *end)
c8250381
AS
300{
301 char *out = *dst;
302
3aeddc7d
RV
303 if (out < end)
304 *out = c;
305 *dst = out + 1;
306 return true;
c8250381
AS
307}
308
3aeddc7d 309static bool escape_space(unsigned char c, char **dst, char *end)
c8250381
AS
310{
311 char *out = *dst;
312 unsigned char to;
313
c8250381
AS
314 switch (c) {
315 case '\n':
316 to = 'n';
317 break;
318 case '\r':
319 to = 'r';
320 break;
321 case '\t':
322 to = 't';
323 break;
324 case '\v':
325 to = 'v';
326 break;
327 case '\f':
328 to = 'f';
329 break;
330 default:
3aeddc7d 331 return false;
c8250381
AS
332 }
333
3aeddc7d
RV
334 if (out < end)
335 *out = '\\';
336 ++out;
337 if (out < end)
338 *out = to;
339 ++out;
c8250381 340
3aeddc7d
RV
341 *dst = out;
342 return true;
c8250381
AS
343}
344
3aeddc7d 345static bool escape_special(unsigned char c, char **dst, char *end)
c8250381
AS
346{
347 char *out = *dst;
348 unsigned char to;
349
c8250381
AS
350 switch (c) {
351 case '\\':
352 to = '\\';
353 break;
354 case '\a':
355 to = 'a';
356 break;
357 case '\e':
358 to = 'e';
359 break;
360 default:
3aeddc7d 361 return false;
c8250381
AS
362 }
363
3aeddc7d
RV
364 if (out < end)
365 *out = '\\';
366 ++out;
367 if (out < end)
368 *out = to;
369 ++out;
c8250381 370
3aeddc7d
RV
371 *dst = out;
372 return true;
c8250381
AS
373}
374
3aeddc7d 375static bool escape_null(unsigned char c, char **dst, char *end)
c8250381
AS
376{
377 char *out = *dst;
378
c8250381 379 if (c)
3aeddc7d 380 return false;
c8250381 381
3aeddc7d
RV
382 if (out < end)
383 *out = '\\';
384 ++out;
385 if (out < end)
386 *out = '0';
387 ++out;
c8250381 388
3aeddc7d
RV
389 *dst = out;
390 return true;
c8250381
AS
391}
392
3aeddc7d 393static bool escape_octal(unsigned char c, char **dst, char *end)
c8250381
AS
394{
395 char *out = *dst;
396
3aeddc7d
RV
397 if (out < end)
398 *out = '\\';
399 ++out;
400 if (out < end)
401 *out = ((c >> 6) & 0x07) + '0';
402 ++out;
403 if (out < end)
404 *out = ((c >> 3) & 0x07) + '0';
405 ++out;
406 if (out < end)
407 *out = ((c >> 0) & 0x07) + '0';
408 ++out;
c8250381
AS
409
410 *dst = out;
3aeddc7d 411 return true;
c8250381
AS
412}
413
3aeddc7d 414static bool escape_hex(unsigned char c, char **dst, char *end)
c8250381
AS
415{
416 char *out = *dst;
417
3aeddc7d
RV
418 if (out < end)
419 *out = '\\';
420 ++out;
421 if (out < end)
422 *out = 'x';
423 ++out;
424 if (out < end)
425 *out = hex_asc_hi(c);
426 ++out;
427 if (out < end)
428 *out = hex_asc_lo(c);
429 ++out;
c8250381
AS
430
431 *dst = out;
3aeddc7d 432 return true;
c8250381
AS
433}
434
435/**
436 * string_escape_mem - quote characters in the given memory buffer
437 * @src: source buffer (unescaped)
438 * @isz: source buffer size
439 * @dst: destination buffer (escaped)
440 * @osz: destination buffer size
441 * @flags: combination of the flags (bitwise OR):
d89a3f73 442 * %ESCAPE_SPACE: (special white space, not space itself)
c8250381
AS
443 * '\f' - form feed
444 * '\n' - new line
445 * '\r' - carriage return
446 * '\t' - horizontal tab
447 * '\v' - vertical tab
448 * %ESCAPE_SPECIAL:
449 * '\\' - backslash
450 * '\a' - alert (BEL)
451 * '\e' - escape
452 * %ESCAPE_NULL:
453 * '\0' - null
454 * %ESCAPE_OCTAL:
455 * '\NNN' - byte with octal value NNN (3 digits)
456 * %ESCAPE_ANY:
457 * all previous together
458 * %ESCAPE_NP:
459 * escape only non-printable characters (checked by isprint)
460 * %ESCAPE_ANY_NP:
461 * all previous together
462 * %ESCAPE_HEX:
463 * '\xHH' - byte with hexadecimal value HH (2 digits)
b40bdb7f
KC
464 * @only: NULL-terminated string containing characters used to limit
465 * the selected escape class. If characters are included in @only
d89a3f73
KC
466 * that would not normally be escaped by the classes selected
467 * in @flags, they will be copied to @dst unescaped.
c8250381
AS
468 *
469 * Description:
470 * The process of escaping byte buffer includes several parts. They are applied
471 * in the following sequence.
472 * 1. The character is matched to the printable class, if asked, and in
473 * case of match it passes through to the output.
b40bdb7f 474 * 2. The character is not matched to the one from @only string and thus
d89a3f73 475 * must go as-is to the output.
c8250381
AS
476 * 3. The character is checked if it falls into the class given by @flags.
477 * %ESCAPE_OCTAL and %ESCAPE_HEX are going last since they cover any
478 * character. Note that they actually can't go together, otherwise
479 * %ESCAPE_HEX will be ignored.
480 *
481 * Caller must provide valid source and destination pointers. Be aware that
482 * destination buffer will not be NULL-terminated, thus caller have to append
483 * it if needs.
484 *
485 * Return:
41416f23
RV
486 * The total size of the escaped output that would be generated for
487 * the given input and flags. To check whether the output was
488 * truncated, compare the return value to osz. There is room left in
489 * dst for a '\0' terminator if and only if ret < osz.
c8250381 490 */
41416f23 491int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
b40bdb7f 492 unsigned int flags, const char *only)
c8250381 493{
41416f23 494 char *p = dst;
3aeddc7d 495 char *end = p + osz;
b40bdb7f 496 bool is_dict = only && *only;
c8250381
AS
497
498 while (isz--) {
499 unsigned char c = *src++;
500
501 /*
502 * Apply rules in the following sequence:
503 * - the character is printable, when @flags has
504 * %ESCAPE_NP bit set
b40bdb7f 505 * - the @only string is supplied and does not contain a
c8250381
AS
506 * character under question
507 * - the character doesn't fall into a class of symbols
508 * defined by given @flags
509 * In these cases we just pass through a character to the
510 * output buffer.
511 */
512 if ((flags & ESCAPE_NP && isprint(c)) ||
b40bdb7f 513 (is_dict && !strchr(only, c))) {
c8250381
AS
514 /* do nothing */
515 } else {
3aeddc7d
RV
516 if (flags & ESCAPE_SPACE && escape_space(c, &p, end))
517 continue;
518
519 if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end))
520 continue;
521
522 if (flags & ESCAPE_NULL && escape_null(c, &p, end))
523 continue;
c8250381
AS
524
525 /* ESCAPE_OCTAL and ESCAPE_HEX always go last */
3aeddc7d 526 if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end))
c8250381 527 continue;
3aeddc7d
RV
528
529 if (flags & ESCAPE_HEX && escape_hex(c, &p, end))
c8250381 530 continue;
c8250381
AS
531 }
532
3aeddc7d 533 escape_passthrough(c, &p, end);
c8250381
AS
534 }
535
41416f23 536 return p - dst;
c8250381
AS
537}
538EXPORT_SYMBOL(string_escape_mem);
b53f27e4
KC
539
540/*
541 * Return an allocated string that has been escaped of special characters
542 * and double quotes, making it safe to log in quotes.
543 */
544char *kstrdup_quotable(const char *src, gfp_t gfp)
545{
546 size_t slen, dlen;
547 char *dst;
548 const int flags = ESCAPE_HEX;
549 const char esc[] = "\f\n\r\t\v\a\e\\\"";
550
551 if (!src)
552 return NULL;
553 slen = strlen(src);
554
555 dlen = string_escape_mem(src, slen, NULL, 0, flags, esc);
556 dst = kmalloc(dlen + 1, gfp);
557 if (!dst)
558 return NULL;
559
560 WARN_ON(string_escape_mem(src, slen, dst, dlen, flags, esc) != dlen);
561 dst[dlen] = '\0';
562
563 return dst;
564}
565EXPORT_SYMBOL_GPL(kstrdup_quotable);
0d044328
KC
566
567/*
568 * Returns allocated NULL-terminated string containing process
569 * command line, with inter-argument NULLs replaced with spaces,
570 * and other special characters escaped.
571 */
572char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp)
573{
574 char *buffer, *quoted;
575 int i, res;
576
577 buffer = kmalloc(PAGE_SIZE, GFP_TEMPORARY);
578 if (!buffer)
579 return NULL;
580
581 res = get_cmdline(task, buffer, PAGE_SIZE - 1);
582 buffer[res] = '\0';
583
584 /* Collapse trailing NULLs, leave res pointing to last non-NULL. */
585 while (--res >= 0 && buffer[res] == '\0')
586 ;
587
588 /* Replace inter-argument NULLs. */
589 for (i = 0; i <= res; i++)
590 if (buffer[i] == '\0')
591 buffer[i] = ' ';
592
593 /* Make sure result is printable. */
594 quoted = kstrdup_quotable(buffer, gfp);
595 kfree(buffer);
596 return quoted;
597}
598EXPORT_SYMBOL_GPL(kstrdup_quotable_cmdline);