Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / common / mime.c
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4  * Ceph - scalable distributed file system
5  *
6  * Copyright (C) 2011 New Dream Network
7  *
8  * This is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License version 2.1, as published by the Free Software
11  * Foundation.  See file COPYING.
12  *
13  */
14 #include "common/utf8.h"
15
16 #include <errno.h>
17 #include <stdio.h>
18
19 int mime_encode_as_qp(const char *input, char *output, int outlen)
20 {
21         int ret = 1;
22         char *o = output;
23         const unsigned char *i = (const unsigned char*)input;
24         while (1) {
25                 int c = *i;
26                 if (c == '\0') {
27                         break;
28                 }
29                 else if ((c & 0x80) || (c == '=') || (is_control_character(c))) {
30                         if (outlen >= 3) {
31                                 snprintf(o, outlen, "=%02X", c);
32                                 outlen -= 3;
33                                 o += 3;
34                         }
35                         else
36                                 outlen = 0;
37                         ret += 3;
38                 }
39                 else {
40                         if (outlen >= 1) {
41                                 snprintf(o, outlen, "%c", c);
42                                 outlen -= 1;
43                                 o += 1;
44                         }
45                         ret += 1;
46                 }
47                 ++i;
48         }
49         return ret;
50 }
51
52 static inline signed int hexchar_to_int(unsigned int c)
53 {
54         switch(c) {
55         case '0':
56                 return 0;
57         case '1':
58                 return 1;
59         case '2':
60                 return 2;
61         case '3':
62                 return 3;
63         case '4':
64                 return 4;
65         case '5':
66                 return 5;
67         case '6':
68                 return 6;
69         case '7':
70                 return 7;
71         case '8':
72                 return 8;
73         case '9':
74                 return 9;
75         case 'A':
76         case 'a':
77                 return 10;
78         case 'B':
79         case 'b':
80                 return 11;
81         case 'C':
82         case 'c':
83                 return 12;
84         case 'D':
85         case 'd':
86                 return 13;
87         case 'E':
88         case 'e':
89                 return 14;
90         case 'F':
91         case 'f':
92                 return 15;
93         case '\0':
94         default:
95             return -EDOM;
96         }
97 }
98
99 int mime_decode_from_qp(const char *input, char *output, int outlen)
100 {
101         int ret = 1;
102         char *o = output;
103         const unsigned char *i = (const unsigned char*)input;
104         while (1) {
105                 unsigned int c = *i;
106                 if (c == '\0') {
107                         break;
108                 }
109                 else if (c & 0x80) {
110                         /* The high bit is never set in quoted-printable encoding! */
111                         return -EDOM;
112                 }
113                 else if (c == '=') {
114                         int high = hexchar_to_int(*++i);
115                         if (high < 0)
116                                 return -EINVAL;
117                         int low = hexchar_to_int(*++i);
118                         if (low < 0)
119                                 return -EINVAL;
120                         c = (high << 4) + low;
121                 }
122                 ++i;
123
124                 if (outlen >= 1) {
125                         snprintf(o, outlen, "%c", c);
126                         outlen -= 1;
127                         o += 1;
128                 }
129                 ret += 1;
130         }
131         return ret;
132 }