865c1b82f6476d4bec35d32241b64351f8138eba
2 * Copyright (C) 2008-2009 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * @defgroup chunk chunk
28 #include <sys/types.h>
33 typedef struct chunk_t chunk_t
;
36 * General purpose pointer/length abstraction.
39 /** Pointer to start of data */
41 /** Length of data in bytes */
48 * A { NULL, 0 }-chunk handy for initialization.
50 extern chunk_t chunk_empty
;
53 * Create a new chunk pointing to "ptr" with length "len"
55 static inline chunk_t
chunk_create(u_char
*ptr
, size_t len
)
57 chunk_t chunk
= {ptr
, len
};
62 * Create a clone of a chunk pointing to "ptr"
64 chunk_t
chunk_create_clone(u_char
*ptr
, chunk_t chunk
);
67 * Calculate length of multiple chunks
69 size_t chunk_length(const char *mode
, ...);
72 * Concatenate chunks into a chunk pointing to "ptr".
74 * The mode string specifies the number of chunks, and how to handle each of
75 * them with a single character: 'c' for copy (allocate new chunk), 'm' for move
76 * (free given chunk) or 's' for sensitive-move (clear given chunk, then free).
78 chunk_t
chunk_create_cat(u_char
*ptr
, const char* mode
, ...);
81 * Split up a chunk into parts, "mode" is a string of "a" (alloc),
82 * "c" (copy) and "m" (move). Each letter say for the corresponding chunk if
83 * it should get allocated on heap, copied into existing chunk, or the chunk
84 * should point into "chunk". The length of each part is an argument before
85 * each target chunk. E.g.:
86 * chunk_split(chunk, "mcac", 3, &a, 7, &b, 5, &c, d.len, &d);
88 void chunk_split(chunk_t chunk
, const char *mode
, ...);
91 * Write the binary contents of a chunk_t to a file
93 * @param chunk contents to write to file
94 * @param path path where file is written to
95 * @param label label specifying file type
96 * @param mask file mode creation mask
97 * @param force overwrite existing file by force
98 * @return TRUE if write operation was successful
100 bool chunk_write(chunk_t chunk
, char *path
, char *label
, mode_t mask
, bool force
);
103 * Convert a chunk of data to hex encoding.
105 * The resulting string is '\\0' terminated, but the chunk does not include
106 * the '\\0'. If buf is supplied, it must hold at least (chunk.len * 2 + 1).
108 * @param chunk data to convert to hex encoding
109 * @param buf buffer to write to, NULL to malloc
110 * @param uppercase TRUE to use uppercase letters
111 * @return chunk of encoded data
113 chunk_t
chunk_to_hex(chunk_t chunk
, char *buf
, bool uppercase
);
116 * Convert a hex encoded in a binary chunk.
118 * If buf is supplied, it must hold at least (hex.len / 2) + (hex.len % 2)
119 * bytes. It is filled by the right to give correct values for short inputs.
121 * @param hex hex encoded input data
122 * @param buf buffer to write decoded data, NULL to malloc
123 * @return converted data
125 chunk_t
chunk_from_hex(chunk_t hex
, char *buf
);
128 * Convert a chunk of data to its base64 encoding.
130 * The resulting string is '\\0' terminated, but the chunk does not include
131 * the '\\0'. If buf is supplied, it must hold at least (chunk.len * 4 / 3 + 1).
133 * @param chunk data to convert
134 * @param buf buffer to write to, NULL to malloc
135 * @return chunk of encoded data
137 chunk_t
chunk_to_base64(chunk_t chunk
, char *buf
);
140 * Convert a base64 in a binary chunk.
142 * If buf is supplied, it must hold at least (base64.len / 4 * 3).
144 * @param base64 base64 encoded input data
145 * @param buf buffer to write decoded data, NULL to malloc
146 * @return converted data
148 chunk_t
chunk_from_base64(chunk_t base64
, char *buf
);
151 * Convert a chunk of data to its base32 encoding.
153 * The resulting string is '\\0' terminated, but the chunk does not include
154 * the '\\0'. If buf is supplied, it must hold (chunk.len * 8 / 5 + 1) bytes.
156 * @param chunk data to convert
157 * @param buf buffer to write to, NULL to malloc
158 * @return chunk of encoded data
160 chunk_t
chunk_to_base32(chunk_t chunk
, char *buf
);
163 * Free contents of a chunk
165 static inline void chunk_free(chunk_t
*chunk
)
168 *chunk
= chunk_empty
;
172 * Overwrite the contents of a chunk and free it
174 static inline void chunk_clear(chunk_t
*chunk
)
178 memwipe(chunk
->ptr
, chunk
->len
);
184 * Initialize a chunk using a char array
186 #define chunk_from_chars(...) ((chunk_t){(char[]){__VA_ARGS__}, sizeof((char[]){__VA_ARGS__})})
189 * Initialize a chunk to point to a thing
191 #define chunk_from_thing(thing) chunk_create((char*)&(thing), sizeof(thing))
194 * Allocate a chunk on the heap
196 #define chunk_alloc(bytes) ({size_t x = (bytes); chunk_create(x ? malloc(x) : NULL, x);})
199 * Allocate a chunk on the stack
201 #define chunk_alloca(bytes) ({size_t x = (bytes); chunk_create(x ? alloca(x) : NULL, x);})
204 * Clone a chunk on heap
206 #define chunk_clone(chunk) ({chunk_t x = (chunk); chunk_create_clone(x.len ? malloc(x.len) : NULL, x);})
209 * Clone a chunk on stack
211 #define chunk_clonea(chunk) ({chunk_t x = (chunk); chunk_create_clone(x.len ? alloca(x.len) : NULL, x);})
214 * Concatenate chunks into a chunk on heap
216 #define chunk_cat(mode, ...) chunk_create_cat(malloc(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
219 * Concatenate chunks into a chunk on stack
221 #define chunk_cata(mode, ...) chunk_create_cat(alloca(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
224 * Skip n bytes in chunk (forward pointer, shorten length)
226 static inline chunk_t
chunk_skip(chunk_t chunk
, size_t bytes
)
228 if (chunk
.len
> bytes
)
238 * Skip a leading zero-valued byte
240 static inline chunk_t
chunk_skip_zero(chunk_t chunk
)
242 if (chunk
.len
> 1 && *chunk
.ptr
== 0x00)
252 * Compare two chunks, returns zero if a equals b
253 * or negative/positive if a is small/greater than b
255 int chunk_compare(chunk_t a
, chunk_t b
);
258 * Compare two chunks for equality,
259 * NULL chunks are never equal.
261 static inline bool chunk_equals(chunk_t a
, chunk_t b
)
263 return a
.ptr
!= NULL
&& b
.ptr
!= NULL
&&
264 a
.len
== b
.len
&& memeq(a
.ptr
, b
.ptr
, a
.len
);
268 * Compare two chunks (given as pointers) for equality (useful as callback),
269 * NULL chunks are never equal.
271 static inline bool chunk_equals_ptr(chunk_t
*a
, chunk_t
*b
)
273 return a
!= NULL
&& b
!= NULL
&& chunk_equals(*a
, *b
);
277 * Increment a chunk, as it would reprensent a network order integer.
279 * @param chunk chunk to increment
280 * @return TRUE if an overflow occurred
282 bool chunk_increment(chunk_t chunk
);
285 * Check if a chunk has printable characters only.
287 * If sane is given, chunk is cloned into sane and all non printable characters
288 * get replaced by "replace".
290 * @param chunk chunk to check for printability
291 * @param sane pointer where sane version is allocated, or NULL
292 * @param replace character to use for replaceing unprintable characters
293 * @return TRUE if all characters in chunk are printable
295 bool chunk_printable(chunk_t chunk
, chunk_t
*sane
, char replace
);
298 * Computes a 32 bit hash of the given chunk.
299 * Note: This hash is only intended for hash tables not for cryptographic purposes.
301 u_int32_t
chunk_hash(chunk_t chunk
);
304 * Incremental version of chunk_hash. Use this to hash two or more chunks.
306 u_int32_t
chunk_hash_inc(chunk_t chunk
, u_int32_t hash
);
309 * printf hook function for chunk_t.
313 * Use #-modifier to print a compact version
315 int chunk_printf_hook(printf_hook_data_t
*data
, printf_hook_spec_t
*spec
,
316 const void *const *args
);
318 #endif /** CHUNK_H_ @}*/