Major manpage overhaul.
[usmb.git] / utils.c
blob0be200d2de08b42fb283e63528a1983cfdf29793
1 /* usmb - mount SMB shares via FUSE and Samba
2 * Copyright (C) 2006-2010 Geoff Johnstone
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "config.h"
18 #include <assert.h>
19 #include <errno.h>
20 #include <limits.h>
21 #include <stdarg.h>
22 #include <stddef.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include "utils.h"
30 #define INIT_LEN 256
31 char * concat_strings (int num, ...)
33 va_list ap;
35 char *base, *out;
37 base = out = malloc (INIT_LEN);
38 if (NULL == base)
39 return NULL;
41 size_t buff_size = INIT_LEN;
43 va_start (ap, num);
44 for (int i = 0; i < num; ++i)
46 const char *next = va_arg (ap, const char *);
47 assert (NULL != next);
49 size_t next_len = strlen (next);
50 /*LINTED*/
51 size_t required = (out - base) + next_len + 1;
53 if (buff_size < required)
55 while (buff_size < required)
57 size_t dbl_len = buff_size * 2;
58 if (dbl_len < buff_size)
60 free (base);
61 va_end (ap);
62 return NULL;
65 buff_size = dbl_len;
68 /*LINTED*/
69 ptrdiff_t diff = out - base;
71 char *newbase = realloc (base, buff_size);
72 if (NULL == newbase)
74 free (base);
75 va_end (ap);
76 return NULL;
79 base = newbase;
80 out = base + diff;
83 memcpy (out, next, next_len);
84 out += next_len;
86 va_end (ap);
88 *out = '\0';
89 return base;
93 char * xstrdup (const char *in)
95 char *out = NULL;
97 if (NULL != in)
99 size_t len = strlen (in) + 1;
101 if ((out = malloc (len)))
102 memcpy (out, in, len);
105 return out;
109 // the const here lets us pass a pointer to const
110 void xfree (const void *ptr)
112 if (NULL != ptr)
113 free ((void *)ptr);
117 void clear_and_free (char *ptr)
119 if (NULL != ptr)
121 for (char *pch = ptr; '\0' != *pch; ++pch)
122 *pch = '\0';
124 free (ptr);
129 void free_errno (const void *ptr)
131 int err = errno;
132 free ((void *)ptr);
133 errno = err;
137 void xfree_errno (const void *ptr)
139 int err = errno;
140 xfree (ptr);
141 errno = err;
145 bool bsnprintf (char *str, size_t size, const char *format, ...)
147 va_list ap;
148 bool ret;
150 va_start (ap, format);
151 ret = bvsnprintf (str, size, format, ap);
152 va_end (ap);
154 return ret;
158 bool bvsnprintf (char *str, size_t size, const char *format, va_list ap)
160 int ret;
162 assert (NULL != str);
163 assert (NULL != format);
165 ret = vsnprintf (str, size, format, ap);
167 return ((ret >= 0) && ((size_t)ret < size));
171 bool baprintf (char **out, const char *format, ...)
173 va_list ap;
174 bool ret;
176 va_start (ap, format);
177 ret = bvaprintf (out, format, ap);
178 va_end (ap);
180 return ret;
184 bool bvaprintf (char **out, const char *format, va_list ap)
186 assert (NULL != out);
187 assert (NULL != format);
188 *out = NULL;
190 int bytes = vsnprintf (NULL, 0, format, ap);
191 if ((1 > bytes) || (INT_MAX == bytes))
192 return false;
194 ++bytes; // '\0'.
196 if (bytes != (int)(size_t)bytes)
197 return false;
199 *out = malloc ((size_t)bytes);
200 if (NULL == *out)
201 return false;
203 if (!bvsnprintf (*out, bytes, format, ap))
205 free (*out);
206 *out = NULL;
207 return false;
210 return true;