1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
5    Copyright (C) 2013-2018 Bareos GmbH & Co. KG
6 
7    This program is Free Software; you can redistribute it and/or
8    modify it under the terms of version three of the GNU Affero General Public
9    License as published by the Free Software Foundation and included
10    in the file LICENSE.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15    Affero General Public License for more details.
16 
17    You should have received a copy of the GNU Affero General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20    02110-1301, USA.
21 */
22 /*
23 
24                    Serialisation Support Functions
25                           John Walker
26 */
27 
28 #include "include/bareos.h"
29 #include "serial.h"
30 
31 /*
32 
33         NOTE:  The following functions should work on any
34                vaguely contemporary platform.  Production
35                builds should use optimised macros (void
36                on platforms with network byte order and IEEE
37                floating point format as native.
38 
39 */
40 
41 /*  serial_int16  --  Serialise a signed 16 bit integer.  */
42 
serial_int16(uint8_t ** const ptr,const int16_t v)43 void serial_int16(uint8_t** const ptr, const int16_t v)
44 {
45   int16_t vo = htons(v);
46 
47   memcpy(*ptr, &vo, sizeof vo);
48   *ptr += sizeof vo;
49 }
50 
51 /*  serial_uint16  --  Serialise an unsigned 16 bit integer.  */
52 
serial_uint16(uint8_t ** const ptr,const uint16_t v)53 void serial_uint16(uint8_t** const ptr, const uint16_t v)
54 {
55   uint16_t vo = htons(v);
56 
57   memcpy(*ptr, &vo, sizeof vo);
58   *ptr += sizeof vo;
59 }
60 
61 /*  serial_int32  --  Serialise a signed 32 bit integer.  */
62 
serial_int32(uint8_t ** const ptr,const int32_t v)63 void serial_int32(uint8_t** const ptr, const int32_t v)
64 {
65   int32_t vo = htonl(v);
66 
67   memcpy(*ptr, &vo, sizeof vo);
68   *ptr += sizeof vo;
69 }
70 
71 /*  serial_uint32  --  Serialise an unsigned 32 bit integer.  */
72 
serial_uint32(uint8_t ** const ptr,const uint32_t v)73 void serial_uint32(uint8_t** const ptr, const uint32_t v)
74 {
75   uint32_t vo = htonl(v);
76 
77   memcpy(*ptr, &vo, sizeof vo);
78   *ptr += sizeof vo;
79 }
80 
81 /*  serial_int64  --  Serialise a signed 64 bit integer.  */
82 
serial_int64(uint8_t ** const ptr,const int64_t v)83 void serial_int64(uint8_t** const ptr, const int64_t v)
84 {
85   if (bigendian()) {
86     memcpy(*ptr, &v, sizeof(int64_t));
87   } else {
88     int i;
89     uint8_t rv[sizeof(int64_t)];
90     uint8_t* pv = (uint8_t*)&v;
91 
92     for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
93     memcpy(*ptr, &rv, sizeof(int64_t));
94   }
95   *ptr += sizeof(int64_t);
96 }
97 
98 
99 /*  serial_uint64  --  Serialise an unsigned 64 bit integer.  */
100 
serial_uint64(uint8_t ** const ptr,const uint64_t v)101 void serial_uint64(uint8_t** const ptr, const uint64_t v)
102 {
103   if (bigendian()) {
104     memcpy(*ptr, &v, sizeof(uint64_t));
105   } else {
106     int i;
107     uint8_t rv[sizeof(uint64_t)];
108     uint8_t* pv = (uint8_t*)&v;
109 
110     for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
111     memcpy(*ptr, &rv, sizeof(uint64_t));
112   }
113   *ptr += sizeof(uint64_t);
114 }
115 
116 
117 /*  SerialBtime  --  Serialise an btime_t 64 bit integer.  */
118 
SerialBtime(uint8_t ** const ptr,const btime_t v)119 void SerialBtime(uint8_t** const ptr, const btime_t v)
120 {
121   if (bigendian()) {
122     memcpy(*ptr, &v, sizeof(btime_t));
123   } else {
124     int i;
125     uint8_t rv[sizeof(btime_t)];
126     uint8_t* pv = (uint8_t*)&v;
127 
128     for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
129     memcpy(*ptr, &rv, sizeof(btime_t));
130   }
131   *ptr += sizeof(btime_t);
132 }
133 
134 
135 /*  serial_float64  --  Serialise a 64 bit IEEE floating point number.
136                         This code assumes that the host floating point
137                         format is IEEE and that floating point quantities
138                         are stored in IEEE format either LSB first or MSB
139                         first.  More creative host formats will require
140                         additional transformations here.  */
141 
serial_float64(uint8_t ** const ptr,const float64_t v)142 void serial_float64(uint8_t** const ptr, const float64_t v)
143 {
144   if (bigendian()) {
145     memcpy(*ptr, &v, sizeof(float64_t));
146   } else {
147     int i;
148     uint8_t rv[sizeof(float64_t)];
149     uint8_t* pv = (uint8_t*)&v;
150 
151     for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
152     memcpy(*ptr, &rv, sizeof(float64_t));
153   }
154   *ptr += sizeof(float64_t);
155 }
156 
SerialString(uint8_t ** const ptr,const char * const str)157 void SerialString(uint8_t** const ptr, const char* const str)
158 {
159   int i;
160   char* dest = (char*)*ptr;
161   char* src = (char*)str;
162   for (i = 0; src[i] != 0; i++) { dest[i] = src[i]; }
163   dest[i++] = 0; /* Terminate output string */
164   *ptr += i;     /* update pointer */
165   // Dmsg2(000, "ser src=%s dest=%s\n", src, dest);
166 }
167 
168 
169 /*  unserial_int16  --  Unserialise a signed 16 bit integer.  */
170 
unserial_int16(uint8_t ** const ptr)171 int16_t unserial_int16(uint8_t** const ptr)
172 {
173   int16_t vo;
174 
175   memcpy(&vo, *ptr, sizeof vo);
176   *ptr += sizeof vo;
177   return ntohs(vo);
178 }
179 
180 /*  unserial_uint16  --  Unserialise an unsigned 16 bit integer.  */
181 
unserial_uint16(uint8_t ** const ptr)182 uint16_t unserial_uint16(uint8_t** const ptr)
183 {
184   uint16_t vo;
185 
186   memcpy(&vo, *ptr, sizeof vo);
187   *ptr += sizeof vo;
188   return ntohs(vo);
189 }
190 
191 /*  unserial_int32  --  Unserialise a signed 32 bit integer.  */
192 
unserial_int32(uint8_t ** const ptr)193 int32_t unserial_int32(uint8_t** const ptr)
194 {
195   int32_t vo;
196 
197   memcpy(&vo, *ptr, sizeof vo);
198   *ptr += sizeof vo;
199   return ntohl(vo);
200 }
201 
202 /*  unserial_uint32  --  Unserialise an unsigned 32 bit integer.  */
203 
unserial_uint32(uint8_t ** const ptr)204 uint32_t unserial_uint32(uint8_t** const ptr)
205 {
206   uint32_t vo;
207 
208   memcpy(&vo, *ptr, sizeof vo);
209   *ptr += sizeof vo;
210   return ntohl(vo);
211 }
212 
213 /*  unserial_uint64  --  Unserialise an unsigned 64 bit integer.  */
214 
unserial_uint64(uint8_t ** const ptr)215 uint64_t unserial_uint64(uint8_t** const ptr)
216 {
217   uint64_t v;
218 
219   if (bigendian()) {
220     memcpy(&v, *ptr, sizeof(uint64_t));
221   } else {
222     int i;
223     uint8_t rv[sizeof(uint64_t)];
224     uint8_t* pv = (uint8_t*)&v;
225 
226     memcpy(&v, *ptr, sizeof(uint64_t));
227     for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
228     memcpy(&v, &rv, sizeof(uint64_t));
229   }
230   *ptr += sizeof(uint64_t);
231   return v;
232 }
233 
234 /*  UnserialBtime  --  Unserialise a btime_t 64 bit integer.  */
235 
UnserialBtime(uint8_t ** const ptr)236 btime_t UnserialBtime(uint8_t** const ptr)
237 {
238   btime_t v;
239 
240   if (bigendian()) {
241     memcpy(&v, *ptr, sizeof(btime_t));
242   } else {
243     int i;
244     uint8_t rv[sizeof(btime_t)];
245     uint8_t* pv = (uint8_t*)&v;
246 
247     memcpy(&v, *ptr, sizeof(btime_t));
248     for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
249     memcpy(&v, &rv, sizeof(btime_t));
250   }
251   *ptr += sizeof(btime_t);
252   return v;
253 }
254 
255 
256 /*  unserial_float64  --  Unserialise a 64 bit IEEE floating point number.
257                          This code assumes that the host floating point
258                          format is IEEE and that floating point quantities
259                          are stored in IEEE format either LSB first or MSB
260                          first.  More creative host formats will require
261                          additional transformations here.  */
262 
unserial_float64(uint8_t ** const ptr)263 float64_t unserial_float64(uint8_t** const ptr)
264 {
265   float64_t v;
266 
267   if (bigendian()) {
268     memcpy(&v, *ptr, sizeof(float64_t));
269   } else {
270     int i;
271     uint8_t rv[sizeof(float64_t)];
272     uint8_t* pv = (uint8_t*)&v;
273 
274     memcpy(&v, *ptr, sizeof(float64_t));
275     for (i = 0; i < 8; i++) { rv[i] = pv[7 - i]; }
276     memcpy(&v, &rv, sizeof(float64_t));
277   }
278   *ptr += sizeof(float64_t);
279   return v;
280 }
281 
UnserialString(uint8_t ** const ptr,char * const str,int max)282 void UnserialString(uint8_t** const ptr, char* const str, int max)
283 {
284   int i;
285   char* src = (char*)(*ptr);
286   char* dest = str;
287   for (i = 0; i < max && src[i] != 0; i++) { dest[i] = src[i]; }
288   dest[i++] = 0; /* Terminate output string */
289   *ptr += i;     /* update pointer */
290   // Dmsg2(000, "unser src=%s dest=%s\n", src, dest);
291 }
292