1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: gnupg |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2006, Thilo Raufeisen <traufeisen@php.net> |
10 | Copyright (c) 2013, Jim Jagielski <jimjag@php.net> |
11 | Copyright (c) 2016, Jakub Zelenka <bukka@php.net> |
12 +--------------------------------------------------------------------+
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18
19 #include <stddef.h>
20
21 #include "php.h"
22 #include "php_ini.h"
23 #include "ext/standard/info.h"
24 #include "zend_interfaces.h"
25 #include "zend_exceptions.h"
26 #include "php_gnupg.h"
27 #include "php_gnupg_keylistiterator.h"
28 #include "phpc/phpc.h"
29
30 static int le_gnupg_keylistiterator;
31
32 static zend_class_entry *gnupg_keylistiterator_class_entry;
33
34 PHPC_OBJ_DEFINE_HANDLER_VAR(gnupg_keylistiterator);
35
36 /* {{{ GNUPG_GET_ITERATOR */
37 #define GNUPG_GET_ITERATOR() \
38 zval *this = getThis(); \
39 PHPC_THIS_DECLARE(gnupg_keylistiterator) = NULL; \
40 do { \
41 if (this) { \
42 PHPC_THIS_FETCH_FROM_ZVAL(gnupg_keylistiterator, this); \
43 if (!PHPC_THIS) { \
44 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid or unitialized gnupg object"); \
45 RETURN_FALSE; \
46 } \
47 } \
48 } while (0)
49 /* }}} */
50
51 /* {{{ free gnupg_keylistiterator */
PHPC_OBJ_HANDLER_FREE(gnupg_keylistiterator)52 PHPC_OBJ_HANDLER_FREE(gnupg_keylistiterator)
53 {
54 PHPC_OBJ_HANDLER_FREE_INIT(gnupg_keylistiterator);
55
56 gpgme_op_keylist_end(PHPC_THIS->ctx);
57 gpgme_key_release(PHPC_THIS->gpgkey);
58 gpgme_release(PHPC_THIS->ctx);
59 if (PHPC_THIS->pattern) {
60 efree(PHPC_THIS->pattern);
61 }
62
63 PHPC_OBJ_HANDLER_FREE_DESTROY();
64 }
65
66 /* {{{ create_ex gnupg_keylistiterator */
PHPC_OBJ_HANDLER_CREATE_EX(gnupg_keylistiterator)67 PHPC_OBJ_HANDLER_CREATE_EX(gnupg_keylistiterator)
68 {
69 PHPC_OBJ_HANDLER_CREATE_EX_INIT(gnupg_keylistiterator);
70
71 gpgme_check_version(NULL);
72
73 gpgme_new(&PHPC_THIS->ctx);
74 PHPC_THIS->err = 0;
75 PHPC_THIS->gpgkey = NULL;
76 PHPC_THIS->pattern = NULL;
77
78 PHPC_OBJ_HANDLER_CREATE_EX_RETURN(gnupg_keylistiterator);
79 }
80
81 /* {{{ create gnupg_keylistiterator */
PHPC_OBJ_HANDLER_CREATE(gnupg_keylistiterator)82 PHPC_OBJ_HANDLER_CREATE(gnupg_keylistiterator)
83 {
84 PHPC_OBJ_HANDLER_CREATE_RETURN(gnupg_keylistiterator);
85 }
86
87
88 /* {{{ arginfo for gnupg void iterator method */
89 ZEND_BEGIN_ARG_INFO_EX(arginfo_gnupg_void_iterator_method, 0, 0, 0)
90 ZEND_END_ARG_INFO()
91 /* }}} */
92
93 /* {{{ method list gnupg_keylistiterator */
94 static zend_function_entry gnupg_keylistiterator_methods[] = {
95 PHP_ME(gnupg_keylistiterator, __construct, arginfo_gnupg_void_iterator_method, ZEND_ACC_PUBLIC)
96 PHP_ME(gnupg_keylistiterator, current, arginfo_gnupg_void_iterator_method, ZEND_ACC_PUBLIC)
97 PHP_ME(gnupg_keylistiterator, key, arginfo_gnupg_void_iterator_method, ZEND_ACC_PUBLIC)
98 PHP_ME(gnupg_keylistiterator, next, arginfo_gnupg_void_iterator_method, ZEND_ACC_PUBLIC)
99 PHP_ME(gnupg_keylistiterator, rewind, arginfo_gnupg_void_iterator_method, ZEND_ACC_PUBLIC)
100 PHP_ME(gnupg_keylistiterator, valid, arginfo_gnupg_void_iterator_method, ZEND_ACC_PUBLIC)
101 PHPC_FE_END
102 };
103 /* }}} */
104
105 /* {{{ _gnupg_keylistiterator_init
106 */
_gnupg_keylistiterator_init(INIT_FUNC_ARGS)107 int _gnupg_keylistiterator_init(INIT_FUNC_ARGS)
108 {
109 zend_class_entry ce;
110
111 /* init class */
112 INIT_CLASS_ENTRY(ce, "gnupg_keylistiterator", gnupg_keylistiterator_methods);
113 PHPC_CLASS_SET_HANDLER_CREATE(ce, gnupg_keylistiterator);
114 gnupg_keylistiterator_class_entry = PHPC_CLASS_REGISTER(ce);
115 PHPC_OBJ_INIT_HANDLERS(gnupg_keylistiterator);
116 PHPC_OBJ_SET_HANDLER_OFFSET(gnupg_keylistiterator);
117 PHPC_OBJ_SET_HANDLER_FREE(gnupg_keylistiterator);
118
119 zend_class_implements(gnupg_keylistiterator_class_entry TSRMLS_CC, 1, zend_ce_iterator);
120
121 le_gnupg_keylistiterator = zend_register_list_destructors_ex(NULL, NULL, "ctx_keylistiterator", module_number);
122
123 return SUCCESS;
124 }
125 /* }}} */
126
127 /* {{{ proto __contruct(string $pattern)
128 * constructs keylistiterator with supplied pattern
129 */
PHP_METHOD(gnupg_keylistiterator,__construct)130 PHP_METHOD(gnupg_keylistiterator, __construct)
131 {
132 char *pattern = NULL;
133 phpc_str_size_t pattern_len;
134
135 int args = ZEND_NUM_ARGS();
136
137 GNUPG_GET_ITERATOR();
138
139 if (args > 0) {
140 if (zend_parse_parameters(args TSRMLS_CC, "|s", &pattern, &pattern_len) == FAILURE) {
141 return;
142 }
143 PHPC_THIS->pattern = estrdup(pattern);
144 }
145 }
146 /* }}} */
147
148 /* {{{ proto string current() */
PHP_METHOD(gnupg_keylistiterator,current)149 PHP_METHOD(gnupg_keylistiterator, current)
150 {
151 GNUPG_GET_ITERATOR();
152
153 PHPC_CSTR_RETURN(PHPC_THIS->gpgkey->uids[0].uid);
154 }
155 /* }}} */
156
157 /* {{{ proto string key() */
PHP_METHOD(gnupg_keylistiterator,key)158 PHP_METHOD(gnupg_keylistiterator, key)
159 {
160 GNUPG_GET_ITERATOR();
161
162 PHPC_CSTR_RETURN(PHPC_THIS->gpgkey->subkeys[0].fpr);
163 }
164 /* }}} */
165
166 /* {{{ proto bool next() */
PHP_METHOD(gnupg_keylistiterator,next)167 PHP_METHOD(gnupg_keylistiterator, next)
168 {
169 GNUPG_GET_ITERATOR();
170
171 if (PHPC_THIS->gpgkey){
172 gpgme_key_release(PHPC_THIS->gpgkey);
173 }
174
175 if ((PHPC_THIS->err = gpgme_op_keylist_next(PHPC_THIS->ctx, &PHPC_THIS->gpgkey))) {
176 gpgme_key_release(PHPC_THIS->gpgkey);
177 PHPC_THIS->gpgkey = NULL;
178 }
179 RETURN_TRUE;
180 }
181 /* }}} */
182
183 /* {{{ proto bool rewind() */
PHP_METHOD(gnupg_keylistiterator,rewind)184 PHP_METHOD(gnupg_keylistiterator, rewind)
185 {
186 GNUPG_GET_ITERATOR();
187
188 if ((PHPC_THIS->err = gpgme_op_keylist_start(
189 PHPC_THIS->ctx, PHPC_THIS->pattern ? PHPC_THIS->pattern : "", 0)) != GPG_ERR_NO_ERROR){
190 zend_throw_exception(zend_exception_get_default(TSRMLS_C), (char *)gpg_strerror(PHPC_THIS->err), 1 TSRMLS_CC);
191 }
192 if ((PHPC_THIS->err = gpgme_op_keylist_next(PHPC_THIS->ctx, &PHPC_THIS->gpgkey)) != GPG_ERR_NO_ERROR){
193 RETURN_FALSE;
194 }
195 RETURN_TRUE;
196 }
197 /* }}} */
198
199 /* {{{ proto bool valid() */
PHP_METHOD(gnupg_keylistiterator,valid)200 PHP_METHOD(gnupg_keylistiterator,valid)
201 {
202 GNUPG_GET_ITERATOR();
203
204 if (PHPC_THIS->gpgkey != NULL) {
205 RETURN_TRUE;
206 } else {
207 RETURN_FALSE;
208 }
209 }
210 /* }}} */
211
212 /*
213 * Local variables:
214 * tab-width: 4
215 * c-basic-offset: 4
216 * End:
217 * vim600: noet sw=4 ts=4 fdm=marker
218 * vim<600: noet sw=4 ts=4
219 */
220