Create an _mtime attribute for new root elements too.
[pwmd.git] / src / misc.c
bloba8ed4ec40d3efbe2a1cdceb3db2609e1ad66da4b
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006-2010 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <unistd.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <glib.h>
27 #include <glib/gprintf.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <gpg-error.h>
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
36 #include "misc.h"
38 void log_write(const gchar *fmt, ...);
40 gboolean strv_printf(gchar ***array, const gchar *fmt, ...)
42 gchar **a;
43 va_list ap;
44 gchar *buf;
45 gint len = *array ? g_strv_length(*array) : 0;
46 gint ret;
48 if (!fmt)
49 return FALSE;
51 if ((a = g_realloc(*array, (len + 2) * sizeof(gchar *))) == NULL) {
52 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
53 return FALSE;
56 va_start(ap, fmt);
57 ret = g_vasprintf(&buf, fmt, ap);
58 va_end(ap);
60 if (ret == -1) {
61 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
62 return FALSE;
65 a[len++] = buf;
66 a[len] = NULL;
67 *array = a;
68 return TRUE;
71 gchar **strvcatv(gchar **dst, gchar **src)
73 gchar **p;
74 gint i;
75 gchar **d;
77 if (!src)
78 return NULL;
80 d = g_strdupv(dst);
82 if (!d)
83 return NULL;
85 i = g_strv_length(d);
87 for (p = src; *p; p++) {
88 gchar **pa;
90 pa = g_realloc(d, (i + 2) * sizeof(gchar *));
92 if (!pa) {
93 g_strfreev(d);
94 return NULL;
97 d = pa;
98 d[i] = g_strdup(*p);
100 if (!d[i]) {
101 g_strfreev(d);
102 return NULL;
105 d[++i] = NULL;
108 return d;
111 gboolean valid_filename(const gchar *filename)
113 const gchar *p;
115 if (!filename || !*filename)
116 return FALSE;
118 if (!strcmp(filename, "-"))
119 return FALSE;
121 for (p = filename; *p; p++) {
122 if (*p == '/' || isspace(*p))
123 return FALSE;
126 return TRUE;
129 gchar *print_fmt(gchar *buf, gsize len, const char *fmt, ...)
131 va_list ap;
133 va_start(ap, fmt);
134 g_vsnprintf(buf, len, fmt, ap);
135 va_end(ap);
136 return buf;
139 gboolean contains_whitespace(const gchar *str)
141 const gchar *p = str;
142 gunichar c;
143 glong len;
145 len = g_utf8_strlen(p++, -1) -1;
147 while (len--) {
148 c = g_utf8_get_char(p++);
150 if (g_unichar_isspace(c))
151 return TRUE;
154 return FALSE;
157 gchar *expand_homedir(gchar *str)
159 gchar *p = str;
161 if (*p++ == '~')
162 return g_strdup_printf("%s%s", g_get_home_dir(), p);
164 return g_strdup(str);
167 gchar *strip_char(gchar *str, gchar c)
169 gchar *p, *p2;
171 for (p = p2 = str; *p; p++) {
172 if (*p == c)
173 continue;
175 *p2++ = *p;
178 *p2 = 0;
179 return str;
182 gchar *tohex(const guchar *str, gsize len)
184 gchar *p;
185 gint i;
187 if (!str || len <= 0)
188 return NULL;
190 p = g_malloc0(len*2+1);
192 if (!p)
193 return NULL;
195 for (i = 0; i < len; i++) {
196 gchar buf[3];
198 g_sprintf(buf, "%02x", str[i]);
199 strcat(p, buf);
202 return p;
205 gchar **split_input_line(gchar *str, gchar *delim, gint n)
207 if (!str || !*str)
208 return NULL;
210 return g_strsplit(str, delim, n);
213 gpg_error_t parse_options(gchar **line, struct argv_s *args[], gpointer data)
215 gchar *p = *line;
216 gpg_error_t rc = 0;
218 for (; p && *p; p++) {
219 while (g_ascii_isspace(*p))
220 p++;
222 if (!*p)
223 break;
225 if (*p == '-' && *(p+1) == '-') {
226 p += 2;
227 gchar opt[255] = {0}, value[255] = {0};
228 gchar *tp;
229 guint len;
231 for (tp = opt, len = 0; *p; p++, len++) {
232 if (len+1 == 255)
233 return GPG_ERR_LINE_TOO_LONG;
235 if (*p == ' ' || *p == '=') {
236 gboolean inquote = FALSE;
238 *tp = 0;
240 if (*p == '=') {
241 p++;
243 for (tp = value, len = 0; *p; p++, len++) {
244 if (len+1 == 255)
245 return GPG_ERR_LINE_TOO_LONG;
247 if (*p == '\"') {
248 inquote = !inquote;
249 continue;
251 else if (*p == ' ' && !inquote)
252 break;
254 *tp++ = *p;
257 *tp = 0;
260 break;
263 *tp++ = *p;
266 *tp = 0;
267 gboolean match = FALSE;
269 for (int i = 0; args[i]; i++) {
270 if (!g_strcmp0(args[i]->opt, opt)) {
271 if (args[i]->type == OPT_NOARG && *value)
272 return GPG_ERR_SYNTAX;
273 else if (args[i]->type == OPT_ARG && !*value)
274 return GPG_ERR_SYNTAX;
276 rc = args[i]->func(data, value);
278 if (rc)
279 return rc;
281 match = TRUE;
282 break;
286 if (!match)
287 return GPG_ERR_UNKNOWN_OPTION;
289 if (!*p)
290 break;
292 continue;
295 break;
298 *line = p;
299 return rc;