2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of pwmd.
7 Pwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Pwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
28 #include <sys/types.h>
35 #include "pwmd-error.h"
37 #include "util-misc.h"
38 #include "util-string.h"
43 extern void log_write(const char *fmt
, ...);
45 int valid_filename(const char *filename
)
49 if (!filename
|| !*filename
)
52 if (!strcmp(filename
, "-"))
55 for (p
= filename
; *p
; p
++) {
56 if (*p
== '/' || isspace(*p
))
65 struct passwd
*pw
= getpwuid(getuid());
67 return pw
? pw
->pw_name
: NULL
;
72 #ifdef HAVE_GETPWNAM_R
73 struct passwd pw
, *result
;
78 return home_directory
;
80 len
= sysconf(_SC_GETPW_R_SIZE_MAX
);
88 if (!getpwuid_r(getuid(), &pw
, buf
, len
, &result
))
89 home_directory
= str_dup(result
->pw_dir
);
93 struct passwd
*result
= getpwuid(getuid());
96 home_directory
= str_dup(result
->pw_dir
);
99 return home_directory
;
102 char *expand_homedir(char *str
)
107 return str_asprintf("%s%s", get_home_dir(), p
);
112 gpg_error_t
parse_options(char **line
, struct argv_s
*args
[], void * data
)
117 for (; p
&& *p
; p
++) {
124 if (*p
== '-' && *(p
+1) == '-') {
126 char opt
[255] = {0}, value
[255] = {0};
130 if (!*p
|| *p
== ' ') {
137 for (tp
= opt
, len
= 0; *p
; p
++, len
++) {
139 return GPG_ERR_LINE_TOO_LONG
;
141 if (*p
== ' ' || *p
== '=') {
149 for (tp
= value
, len
= 0; *p
; p
++, len
++) {
151 return GPG_ERR_LINE_TOO_LONG
;
157 else if (*p
== ' ' && !inquote
)
175 for (int i
= 0; args
[i
]; i
++) {
176 if (!strcmp(args
[i
]->opt
, opt
)) {
177 log_write1("param: name='%s' value='%s'", opt
, value
);
178 if (args
[i
]->type
== OPTION_TYPE_NOARG
&& *value
)
179 return GPG_ERR_SYNTAX
;
180 else if (args
[i
]->type
== OPTION_TYPE_ARG
&& !*value
)
181 return GPG_ERR_SYNTAX
;
183 rc
= args
[i
]->func(data
, value
);
194 return GPG_ERR_UNKNOWN_OPTION
;
209 char *bin2hex(const unsigned char *data
, size_t len
)
211 size_t size
= len
*2+1;
217 for (n
= 0; n
< len
; n
++) {
220 sprintf(c
, "%02X", data
[n
]);
227 char *plus_escape(const char *fmt
, ...)
234 if (str_vasprintf(&str
, fmt
, ap
) > 0) {
237 for (p
= str
; *p
; p
++) {
250 static char *strip_texi(const char *str
)
253 char *s
= str_dup(str
);
259 for (p
= str
; *p
; p
++) {
260 if (*p
== '@' && *(p
+1) != '@') {
261 if (!strncasecmp(p
+1, "table", 5)
262 || !strncasecmp(p
+1, "end ", 4)) {
263 while (*p
++ != '\n');
267 else if (!strncasecmp(p
+1, "example", 7)
268 || !strncasecmp(p
+1, "end ", 4)) {
269 while (*p
++ != '\n');
273 else if (!strncasecmp(p
+1, "sp ", 3)) {
276 while (*p
&& isdigit(*p
++))
280 else if (!strncasecmp(p
+1, "item", 4)) {
282 while (*p
&& *p
!= '\n')
287 else if (!strncasecmp(p
+1, "pxref", 5)) {
293 else if (!strncasecmp(p
+1, "xref", 4)) {
300 while (*p
&& *p
!= '{') {
311 while (*p
&& *p
!= '}')
320 else if (*p
== '@' && *(p
+1) == '@')
335 char *strip_texi_and_wrap(const char *str
)
337 char *tmp
= strip_texi(str
);
338 char *help
= xmalloc(strlen(tmp
+1)*2);
342 for (p
= tmp
, ph
= help
, i
= 0; *p
; p
++, i
++) {
343 if (i
== 78 || *p
== '\n') {
348 while (!(*--t
== ' '))
362 while (*p
!= '\n' && *p
== ' ')
375 void free_key(void *data
)
380 gpg_error_t
create_thread(void *(*cb
)(void *), void *data
,
381 pthread_t
*tid
, int detached
)
386 pthread_attr_init(&attr
);
389 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
391 n
= pthread_create(tid
, &attr
, cb
, data
);
392 pthread_attr_destroy(&attr
);
393 return gpg_error_from_errno(n
);
396 void cleanup_mutex_cb(void *arg
)
398 pthread_mutex_t
*m
= (pthread_mutex_t
*)arg
;
403 void cleanup_fd_cb(void *arg
)
405 int fd
= *(int *)arg
;
411 void cleanup_unlink_cb(void *arg
)
419 void cleanup_cache_mutex(void *arg
)
424 int valid_keygrip(const unsigned char *data
, size_t len
)
426 for (size_t i
= 0; i
< len
; i
++) {
434 gpg_error_t
get_checksum(const char *filename
, unsigned char **r_crc
, size_t *r_crclen
)
442 if (stat(filename
, &st
) == -1)
443 return gpg_error_from_syserror();
445 fd
= open(filename
, O_RDONLY
);
447 return gpg_error_from_syserror();
449 pthread_cleanup_push(cleanup_fd_cb
, &fd
);
450 buf
= xmalloc(st
.st_size
);
452 pthread_cleanup_push(xfree
, buf
);
454 len
= read(fd
, buf
, st
.st_size
);
455 if (len
== st
.st_size
) {
459 len
= gcry_md_get_algo_dlen(GCRY_MD_CRC32
);
462 pthread_cleanup_push(xfree
, crc
);
463 gcry_md_hash_buffer(GCRY_MD_CRC32
, crc
, buf
, st
.st_size
);
466 pthread_cleanup_pop(0);
473 rc
= GPG_ERR_TOO_SHORT
;
475 pthread_cleanup_pop(1);
480 pthread_cleanup_pop(1);