summaryrefslogtreecommitdiffstats
path: root/src/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils.c')
-rw-r--r--src/utils.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/utils.c b/src/utils.c
index ceef535..475a921 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -3,6 +3,7 @@
3 3
4Copyright (C) 2009 Hector Martin "marcan" <hector@marcansoft.com> 4Copyright (C) 2009 Hector Martin "marcan" <hector@marcansoft.com>
5Copyright (C) 2009 Nikias Bassen <nikias@gmx.li> 5Copyright (C) 2009 Nikias Bassen <nikias@gmx.li>
6Copyright (c) 2013 Federico Mena Quintero
6 7
7This library is free software; you can redistribute it and/or modify 8This library is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as 9it under the terms of the GNU Lesser General Public License as
@@ -27,6 +28,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27#include <stdlib.h> 28#include <stdlib.h>
28#include <string.h> 29#include <string.h>
29#include <stdio.h> 30#include <stdio.h>
31#include <stdarg.h>
32
30#include "utils.h" 33#include "utils.h"
31 34
32#include "log.h" 35#include "log.h"
@@ -118,3 +121,144 @@ int collection_count(struct collection *col)
118 } 121 }
119 return cnt; 122 return cnt;
120} 123}
124
125#ifndef HAVE_STPCPY
126/**
127 * Copy characters from one string into another
128 *
129 * @note: The strings should not overlap, as the behavior is undefined.
130 *
131 * @s1: The source string.
132 * @s2: The destination string.
133 *
134 * @return a pointer to the terminating `\0' character of @s1,
135 * or NULL if @s1 or @s2 is NULL.
136 */
137char *stpcpy(char * s1, const char * s2)
138{
139 if (s1 == NULL || s2 == NULL)
140 return NULL;
141
142 strcpy(s1, s2);
143
144 return s1 + strlen(s2);
145}
146#endif
147
148/**
149 * Concatenate strings into a newly allocated string
150 *
151 * @note: Specify NULL for the last string in the varargs list
152 *
153 * @str: The first string in the list
154 * @...: Subsequent strings. Use NULL for the last item.
155 *
156 * @return a newly allocated string, or NULL if @str is NULL. This will also
157 * return NULL and set errno to ENOMEM if memory is exhausted.
158 */
159char *string_concat(const char *str, ...)
160{
161 size_t len;
162 va_list args;
163 char *s;
164 char *result;
165 char *dest;
166
167 if (!str)
168 return NULL;
169
170 /* Compute final length */
171
172 len = strlen(str) + 1; /* plus 1 for the null terminator */
173
174 va_start(args, str);
175 s = va_arg(args, char *);
176 while (s) {
177 len += strlen(s);
178 s = va_arg(args, char*);
179 }
180 va_end(args);
181
182 /* Concat each string */
183
184 result = malloc(len);
185 if (!result)
186 return NULL; /* errno remains set */
187
188 dest = result;
189
190 dest = stpcpy(dest, str);
191
192 va_start(args, str);
193 s = va_arg(args, char *);
194 while (s) {
195 dest = stpcpy(dest, s);
196 s = va_arg(args, char *);
197 }
198 va_end(args);
199
200 return result;
201}
202
203void buffer_read_from_filename(const char *filename, char **buffer, uint64_t *length)
204{
205 FILE *f;
206 uint64_t size;
207
208 *length = 0;
209
210 f = fopen(filename, "rb");
211 if (!f) {
212 return;
213 }
214
215 fseek(f, 0, SEEK_END);
216 size = ftell(f);
217 rewind(f);
218
219 if (size == 0) {
220 fclose(f);
221 return;
222 }
223
224 *buffer = (char*)malloc(sizeof(char)*(size+1));
225 if (fread(*buffer, sizeof(char), size, f) != size) {
226 usbmuxd_log(LL_ERROR, "%s: ERROR: couldn't read %d bytes from %s\n", __func__, (int)size, filename);
227 }
228 fclose(f);
229
230 *length = size;
231}
232
233void buffer_write_to_filename(const char *filename, const char *buffer, uint64_t length)
234{
235 FILE *f;
236
237 f = fopen(filename, "wb");
238 if (f) {
239 fwrite(buffer, sizeof(char), length, f);
240 fclose(f);
241 }
242}
243
244int plist_write_to_filename(plist_t plist, const char *filename, enum plist_format_t format)
245{
246 char *buffer = NULL;
247 uint32_t length;
248
249 if (!plist || !filename)
250 return 0;
251
252 if (format == PLIST_FORMAT_XML)
253 plist_to_xml(plist, &buffer, &length);
254 else if (format == PLIST_FORMAT_BINARY)
255 plist_to_bin(plist, &buffer, &length);
256 else
257 return 0;
258
259 buffer_write_to_filename(filename, buffer, length);
260
261 free(buffer);
262
263 return 1;
264}