Line data Source code
1 : /*
2 : configuration.cpp - wraps gpgme configuration components
3 : Copyright (C) 2010 Klarälvdalens Datakonsult AB
4 :
5 : This file is part of GPGME++.
6 :
7 : GPGME++ is free software; you can redistribute it and/or
8 : modify it under the terms of the GNU Library General Public
9 : License as published by the Free Software Foundation; either
10 : version 2 of the License, or (at your option) any later version.
11 :
12 : GPGME++ 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 Library General Public License for more details.
16 :
17 : You should have received a copy of the GNU Library General Public License
18 : along with GPGME++; see the file COPYING.LIB. If not, write to the
19 : Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 : Boston, MA 02110-1301, USA.
21 : */
22 :
23 : #ifdef HAVE_CONFIG_H
24 : #include "config.h"
25 : #endif
26 :
27 : #include "configuration.h"
28 : #include "error.h"
29 : #include "util.h"
30 :
31 : #include <gpgme.h>
32 :
33 : #include <iterator>
34 : #include <algorithm>
35 : #include <ostream>
36 : #include <cstring>
37 : #include <assert.h>
38 :
39 : using namespace GpgME;
40 : using namespace GpgME::Configuration;
41 :
42 : typedef std::shared_ptr< std::remove_pointer<gpgme_conf_opt_t>::type > shared_gpgme_conf_opt_t;
43 : typedef std::weak_ptr< std::remove_pointer<gpgme_conf_opt_t>::type > weak_gpgme_conf_opt_t;
44 :
45 : typedef std::shared_ptr< std::remove_pointer<gpgme_conf_arg_t>::type > shared_gpgme_conf_arg_t;
46 : typedef std::weak_ptr< std::remove_pointer<gpgme_conf_arg_t>::type > weak_gpgme_conf_arg_t;
47 :
48 : typedef std::shared_ptr< std::remove_pointer<gpgme_ctx_t>::type > shared_gpgme_ctx_t;
49 : typedef std::weak_ptr< std::remove_pointer<gpgme_ctx_t>::type > weak_gpgme_ctx_t;
50 :
51 : namespace
52 : {
53 : struct nodelete {
54 : template <typename T> void operator()(T *) {}
55 : };
56 : }
57 :
58 : // static
59 0 : std::vector<Component> Component::load(Error &returnedError)
60 : {
61 :
62 : //
63 : // 1. get a context:
64 : //
65 0 : gpgme_ctx_t ctx_native = 0;
66 0 : if (const gpgme_error_t err = gpgme_new(&ctx_native)) {
67 0 : returnedError = Error(err);
68 0 : return std::vector<Component>();
69 : }
70 0 : const shared_gpgme_ctx_t ctx(ctx_native, &gpgme_release);
71 :
72 : //
73 : // 2. load the config:
74 : //
75 0 : gpgme_conf_comp_t conf_list_native = 0;
76 0 : if (const gpgme_error_t err = gpgme_op_conf_load(ctx_native, &conf_list_native)) {
77 0 : returnedError = Error(err);
78 0 : return std::vector<Component>();
79 : }
80 0 : shared_gpgme_conf_comp_t head(conf_list_native, &gpgme_conf_release);
81 :
82 : //
83 : // 3. convert to vector<Component>:
84 : //
85 0 : std::vector<Component> result;
86 :
87 0 : while (head) {
88 : // secure 'head->next' (if any) against memleaks:
89 0 : shared_gpgme_conf_comp_t next;
90 0 : if (head->next) {
91 0 : next.reset(head->next, &gpgme_conf_release);
92 : }
93 :
94 : // now prevent double-free of next.get() and following:
95 0 : head->next = 0;
96 :
97 : // now add a new Component to 'result' (may throw):
98 0 : result.resize(result.size() + 1);
99 0 : result.back().comp.swap(head); // .comp = std::move( head );
100 0 : head.swap(next); // head = std::move( next );
101 : }
102 :
103 0 : return result;
104 : }
105 :
106 0 : Error Component::save() const
107 : {
108 :
109 0 : if (isNull()) {
110 0 : return Error(make_error(GPG_ERR_INV_ARG));
111 : }
112 :
113 : //
114 : // 1. get a context:
115 : //
116 0 : gpgme_ctx_t ctx_native = 0;
117 0 : if (const gpgme_error_t err = gpgme_new(&ctx_native)) {
118 0 : return Error(err);
119 : }
120 0 : const shared_gpgme_ctx_t ctx(ctx_native, &gpgme_release);
121 :
122 : //
123 : // 2. save the config:
124 : //
125 0 : return Error(gpgme_op_conf_save(ctx.get(), comp.get()));
126 : }
127 :
128 0 : const char *Component::name() const
129 : {
130 0 : return comp ? comp->name : 0 ;
131 : }
132 :
133 0 : const char *Component::description() const
134 : {
135 0 : return comp ? comp->description : 0 ;
136 : }
137 :
138 0 : const char *Component::programName() const
139 : {
140 0 : return comp ? comp->program_name : 0 ;
141 : }
142 :
143 0 : Option Component::option(unsigned int idx) const
144 : {
145 0 : gpgme_conf_opt_t opt = 0;
146 0 : if (comp) {
147 0 : opt = comp->options;
148 : }
149 0 : while (opt && idx) {
150 0 : opt = opt->next;
151 0 : --idx;
152 : }
153 0 : if (opt) {
154 0 : return Option(comp, opt);
155 : }
156 0 : return Option();
157 : }
158 :
159 0 : Option Component::option(const char *name) const
160 : {
161 0 : gpgme_conf_opt_t opt = 0;
162 0 : if (comp) {
163 0 : opt = comp->options;
164 : }
165 : using namespace std; // for strcmp
166 0 : while (opt && strcmp(name, opt->name) != 0) {
167 0 : opt = opt->next;
168 : }
169 0 : if (opt) {
170 0 : return Option(comp, opt);
171 : }
172 0 : return Option();
173 : }
174 :
175 0 : unsigned int Component::numOptions() const
176 : {
177 0 : unsigned int result = 0;
178 0 : for (gpgme_conf_opt_t opt = comp ? comp->options : 0 ; opt ; opt = opt->next) {
179 0 : ++result;
180 : }
181 0 : return result;
182 : }
183 :
184 0 : std::vector<Option> Component::options() const
185 : {
186 0 : std::vector<Option> result;
187 0 : for (gpgme_conf_opt_t opt = comp ? comp->options : 0 ; opt ; opt = opt->next) {
188 0 : result.push_back(Option(comp, opt));
189 : }
190 0 : return result;
191 : }
192 :
193 0 : static gpgme_conf_arg_t mygpgme_conf_arg_copy(gpgme_conf_arg_t other, gpgme_conf_type_t type)
194 : {
195 0 : gpgme_conf_arg_t result = 0, last = 0;
196 0 : for (gpgme_conf_arg_t a = other ; a ; a = a->next) {
197 0 : gpgme_conf_arg_t arg = 0;
198 : const gpgme_error_t err
199 0 : = gpgme_conf_arg_new(&arg, type,
200 0 : a->no_arg ? 0 :
201 : type == GPGME_CONF_STRING ? a->value.string :
202 0 : /* else */ static_cast<void *>(&a->value));
203 0 : if (err) {
204 0 : gpgme_conf_arg_release(result, type);
205 0 : return 0;
206 : }
207 0 : assert(arg);
208 0 : if (result) {
209 0 : last->next = arg;
210 : } else {
211 0 : result = arg;
212 : }
213 0 : last = arg;
214 : }
215 0 : return result;
216 : }
217 :
218 0 : Component Option::parent() const
219 : {
220 0 : return Component(comp.lock());
221 : }
222 :
223 0 : unsigned int Option::flags() const
224 : {
225 0 : return isNull() ? 0 : opt->flags;
226 : }
227 :
228 0 : Level Option::level() const
229 : {
230 0 : return isNull() ? Internal : static_cast<Level>(opt->level) ;
231 : }
232 :
233 0 : const char *Option::name() const
234 : {
235 0 : return isNull() ? 0 : opt->name ;
236 : }
237 :
238 0 : const char *Option::description() const
239 : {
240 0 : return isNull() ? 0 : opt->description ;
241 : }
242 :
243 0 : const char *Option::argumentName() const
244 : {
245 0 : return isNull() ? 0 : opt->argname ;
246 : }
247 :
248 0 : Type Option::type() const
249 : {
250 0 : return isNull() ? NoType : static_cast<Type>(opt->type) ;
251 : }
252 :
253 0 : Type Option::alternateType() const
254 : {
255 0 : return isNull() ? NoType : static_cast<Type>(opt->alt_type) ;
256 : }
257 :
258 : #if 0
259 : static Option::Variant argument_to_variant(gpgme_conf_type_t type, bool list, gpgme_conf_arg_t arg)
260 : {
261 : assert(arg);
262 : switch (type) {
263 : case GPGME_CONF_NONE:
264 : if (list) {
265 : // return the count (number of times set):
266 : return arg->value.count;
267 : } else {
268 : return none;
269 : }
270 : case GPGME_CONF_INT32:
271 : if (list) {
272 : std::vector<int> result;
273 : for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
274 : result.push_back(a->value.int32);
275 : }
276 : return result;
277 : } else {
278 : return arg->value.int32;
279 : }
280 : case GPGME_CONF_UINT32:
281 : if (list) {
282 : std::vector<unsigned int> result;
283 : for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
284 : result.push_back(a->value.uint32);
285 : }
286 : return result;
287 : } else {
288 : return arg->value.uint32;
289 : }
290 : case GPGME_CONF_FILENAME:
291 : case GPGME_CONF_LDAP_SERVER:
292 : case GPGME_CONF_KEY_FPR:
293 : case GPGME_CONF_PUB_KEY:
294 : case GPGME_CONF_SEC_KEY:
295 : case GPGME_CONF_ALIAS_LIST:
296 : // these should not happen in alt_type, but fall through
297 : case GPGME_CONF_STRING:
298 : if (list) {
299 : std::vector<const char *> result;
300 : for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
301 : result.push_back(a->value.string);
302 : }
303 : return result;
304 : } else {
305 : return arg->value.string;
306 : }
307 : }
308 : assert(!"Option: unknown alt_type!");
309 : return Option::Variant();
310 : }
311 :
312 : namespace
313 : {
314 : inline const void *to_void_star(const char *s)
315 : {
316 : return s;
317 : }
318 : inline const void *to_void_star(const std::string &s)
319 : {
320 : return s.c_str();
321 : }
322 : inline const void *to_void_star(const int &i)
323 : {
324 : return &i; // const-&: sic!
325 : }
326 : inline const void *to_void_star(const unsigned int &i)
327 : {
328 : return &i; // const-&: sic!
329 : }
330 :
331 : struct VariantToArgumentVisitor : boost::static_visitor<gpgme_conf_arg_t> {
332 : static gpgme_conf_arg_t make_argument(gpgme_conf_type_t type, const void *value)
333 : {
334 : gpgme_conf_arg_t arg = 0;
335 : #ifdef HAVE_GPGME_CONF_ARG_NEW_WITH_CONST_VALUE
336 : if (const gpgme_error_t err = gpgme_conf_arg_new(&arg, type, value)) {
337 : return 0;
338 : }
339 : #else
340 : if (const gpgme_error_t err = gpgme_conf_arg_new(&arg, type, const_cast<void *>(value))) {
341 : return 0;
342 : }
343 : #endif
344 : else {
345 : return arg;
346 : }
347 : }
348 :
349 : gpgme_conf_arg_t operator()(bool v) const
350 : {
351 : return v ? make_argument(0) : 0 ;
352 : }
353 :
354 : gpgme_conf_arg_t operator()(const char *s) const
355 : {
356 : return make_argument(s ? s : "");
357 : }
358 :
359 : gpgme_conf_arg_t operator()(const std::string &s) const
360 : {
361 : return operator()(s.c_str());
362 : }
363 :
364 : gpgme_conf_arg_t operator()(int i) const
365 : {
366 : return make_argument(&i);
367 : }
368 :
369 : gpgme_conf_arg_t operator()(unsigned int i) const
370 : {
371 : return make_argument(&i);
372 : }
373 :
374 : template <typename T>
375 : gpgme_conf_arg_t operator()(const std::vector<T> &value) const
376 : {
377 : gpgme_conf_arg_t result = 0;
378 : gpgme_conf_arg_t last = 0;
379 : for (typename std::vector<T>::const_iterator it = value.begin(), end = value.end() ; it != end ; ++it) {
380 : if (gpgme_conf_arg_t arg = make_argument(to_void_star(*it))) {
381 : if (last) {
382 : last = last->next = arg;
383 : } else {
384 : result = last = arg;
385 : }
386 : }
387 : }
388 : return result;
389 : }
390 :
391 : };
392 : }
393 :
394 : static gpgme_conf_arg_t variant_to_argument(const Option::Variant &value)
395 : {
396 : VariantToArgumentVisitor v;
397 : return apply_visitor(v, value);
398 : }
399 :
400 : optional<Option::Variant> Option::defaultValue() const
401 : {
402 : if (isNull()) {
403 : return optional<Variant>();
404 : } else {
405 : return argument_to_variant(opt->alt_type, opt->flags & GPGME_CONF_LIST, opt->default_value);
406 : }
407 : }
408 : #endif
409 :
410 0 : Argument Option::defaultValue() const
411 : {
412 0 : if (isNull()) {
413 0 : return Argument();
414 : } else {
415 0 : return Argument(comp.lock(), opt, opt->default_value, false);
416 : }
417 : }
418 :
419 0 : const char *Option::defaultDescription() const
420 : {
421 0 : return isNull() ? 0 : opt->default_description ;
422 : }
423 :
424 0 : Argument Option::noArgumentValue() const
425 : {
426 0 : if (isNull()) {
427 0 : return Argument();
428 : } else {
429 0 : return Argument(comp.lock(), opt, opt->no_arg_value, false);
430 : }
431 : }
432 :
433 0 : const char *Option::noArgumentDescription() const
434 : {
435 0 : return isNull() ? 0 : opt->no_arg_description ;
436 : }
437 :
438 0 : Argument Option::activeValue() const
439 : {
440 0 : if (isNull()) {
441 0 : return Argument();
442 : } else {
443 0 : return Argument(comp.lock(), opt, opt->value, false);
444 : }
445 : }
446 :
447 0 : Argument Option::currentValue() const
448 : {
449 0 : if (isNull()) {
450 0 : return Argument();
451 : }
452 : const gpgme_conf_arg_t arg =
453 0 : opt->change_value ? opt->new_value ? opt->new_value : opt->default_value :
454 0 : opt->value ? opt->value :
455 0 : /* else */ opt->default_value ;
456 0 : return Argument(comp.lock(), opt, arg, false);
457 : }
458 :
459 0 : Argument Option::newValue() const
460 : {
461 0 : if (isNull()) {
462 0 : return Argument();
463 : } else {
464 0 : return Argument(comp.lock(), opt, opt->new_value, false);
465 : }
466 : }
467 :
468 0 : bool Option::set() const
469 : {
470 0 : if (isNull()) {
471 0 : return false;
472 0 : } else if (opt->change_value) {
473 0 : return opt->new_value;
474 : } else {
475 0 : return opt->value;
476 : }
477 : }
478 :
479 0 : bool Option::dirty() const
480 : {
481 0 : return !isNull() && opt->change_value ;
482 : }
483 :
484 0 : Error Option::setNewValue(const Argument &argument)
485 : {
486 0 : if (isNull()) {
487 0 : return Error(make_error(GPG_ERR_INV_ARG));
488 0 : } else if (argument.isNull()) {
489 0 : return resetToDefaultValue();
490 0 : } else if (const gpgme_conf_arg_t arg = mygpgme_conf_arg_copy(argument.arg, opt->alt_type)) {
491 0 : return Error(gpgme_conf_opt_change(opt, 0, arg));
492 : } else {
493 0 : return Error(make_error(GPG_ERR_ENOMEM));
494 : }
495 : }
496 :
497 0 : Error Option::resetToActiveValue()
498 : {
499 0 : if (isNull()) {
500 0 : return Error(make_error(GPG_ERR_INV_ARG));
501 : } else {
502 0 : return Error(gpgme_conf_opt_change(opt, 1, 0));
503 : }
504 : }
505 :
506 0 : Error Option::resetToDefaultValue()
507 : {
508 0 : if (isNull()) {
509 0 : return Error(make_error(GPG_ERR_INV_ARG));
510 : } else {
511 0 : return Error(gpgme_conf_opt_change(opt, 0, 0));
512 : }
513 : }
514 :
515 0 : static gpgme_conf_arg_t make_argument(gpgme_conf_type_t type, const void *value)
516 : {
517 0 : gpgme_conf_arg_t arg = 0;
518 0 : if (const gpgme_error_t err = gpgme_conf_arg_new(&arg, type, value)) {
519 0 : return 0;
520 : } else {
521 0 : return arg;
522 : }
523 : }
524 :
525 0 : Argument Option::createNoneArgument(bool set) const
526 : {
527 0 : if (isNull() || alternateType() != NoType) {
528 0 : return Argument();
529 : } else {
530 0 : if (set) {
531 0 : return createNoneListArgument(1);
532 : }
533 : }
534 0 : return Argument();
535 : }
536 :
537 0 : Argument Option::createStringArgument(const char *value) const
538 : {
539 0 : if (isNull() || alternateType() != StringType) {
540 0 : return Argument();
541 : } else {
542 0 : return Argument(comp.lock(), opt, make_argument(GPGME_CONF_STRING, value), true);
543 : }
544 : }
545 :
546 0 : Argument Option::createStringArgument(const std::string &value) const
547 : {
548 0 : if (isNull() || alternateType() != StringType) {
549 0 : return Argument();
550 : } else {
551 0 : return Argument(comp.lock(), opt, make_argument(GPGME_CONF_STRING, value.c_str()), true);
552 : }
553 : }
554 :
555 0 : Argument Option::createIntArgument(int value) const
556 : {
557 0 : if (isNull() || alternateType() != IntegerType) {
558 0 : return Argument();
559 : } else {
560 0 : return Argument(comp.lock(), opt, make_argument(GPGME_CONF_INT32, &value), true);
561 : }
562 : }
563 :
564 0 : Argument Option::createUIntArgument(unsigned int value) const
565 : {
566 0 : if (isNull() || alternateType() != UnsignedIntegerType) {
567 0 : return Argument();
568 : } else {
569 0 : return Argument(comp.lock(), opt, make_argument(GPGME_CONF_UINT32, &value), true);
570 : }
571 : }
572 :
573 : namespace
574 : {
575 0 : const void *to_void_star(const char *s)
576 : {
577 0 : return s;
578 : }
579 0 : const void *to_void_star(const std::string &s)
580 : {
581 0 : return s.c_str();
582 : }
583 0 : const void *to_void_star(const int &i)
584 : {
585 0 : return &i; // const-&: sic!
586 : }
587 0 : const void *to_void_star(const unsigned int &i)
588 : {
589 0 : return &i; // const-&: sic!
590 : }
591 :
592 : template <typename T>
593 0 : gpgme_conf_arg_t make_argument(gpgme_conf_type_t type, const std::vector<T> &value)
594 : {
595 0 : gpgme_conf_arg_t result = 0;
596 0 : gpgme_conf_arg_t last = 0;
597 0 : for (typename std::vector<T>::const_iterator it = value.begin(), end = value.end() ; it != end ; ++it) {
598 0 : if (gpgme_conf_arg_t arg = make_argument(type, to_void_star(*it))) {
599 0 : if (last) {
600 0 : last = last->next = arg;
601 : } else {
602 0 : result = last = arg;
603 : }
604 : }
605 : }
606 0 : return result;
607 : }
608 : }
609 :
610 0 : Argument Option::createNoneListArgument(unsigned int value) const
611 : {
612 0 : if (value) {
613 0 : return Argument(comp.lock(), opt, make_argument(GPGME_CONF_NONE, &value), true);
614 : }
615 0 : return Argument();
616 : }
617 :
618 0 : Argument Option::createStringListArgument(const std::vector<const char *> &value) const
619 : {
620 0 : return Argument(comp.lock(), opt, make_argument(GPGME_CONF_STRING, value), true);
621 : }
622 :
623 0 : Argument Option::createStringListArgument(const std::vector<std::string> &value) const
624 : {
625 0 : return Argument(comp.lock(), opt, make_argument(GPGME_CONF_STRING, value), true);
626 : }
627 :
628 0 : Argument Option::createIntListArgument(const std::vector<int> &value) const
629 : {
630 0 : return Argument(comp.lock(), opt, make_argument(GPGME_CONF_INT32, value), true);
631 : }
632 :
633 0 : Argument Option::createUIntListArgument(const std::vector<unsigned int> &value) const
634 : {
635 0 : return Argument(comp.lock(), opt, make_argument(GPGME_CONF_UINT32, value), true);
636 : }
637 :
638 0 : Argument::Argument(const shared_gpgme_conf_comp_t &comp, gpgme_conf_opt_t opt, gpgme_conf_arg_t arg, bool owns)
639 : : comp(comp),
640 : opt(opt),
641 0 : arg(owns ? arg : mygpgme_conf_arg_copy(arg, opt ? opt->alt_type : GPGME_CONF_NONE))
642 : {
643 :
644 0 : }
645 :
646 : #if 0
647 : Argument::Argument(const shared_gpgme_conf_comp_t &comp, gpgme_conf_opt_t opt, gpgme_conf_arg_t arg)
648 : : comp(comp),
649 : opt(opt),
650 : arg(mygpgme_conf_arg_copy(arg, opt ? opt->alt_type : GPGME_CONF_NONE))
651 : {
652 :
653 : }
654 : #endif
655 :
656 0 : Argument::Argument(const Argument &other)
657 : : comp(other.comp),
658 0 : opt(other.opt),
659 0 : arg(mygpgme_conf_arg_copy(other.arg, opt ? opt->alt_type : GPGME_CONF_NONE))
660 : {
661 :
662 0 : }
663 :
664 0 : Argument::~Argument()
665 : {
666 0 : gpgme_conf_arg_release(arg, opt ? opt->alt_type : GPGME_CONF_NONE);
667 0 : }
668 :
669 0 : Option Argument::parent() const
670 : {
671 0 : return Option(comp.lock(), opt);
672 : }
673 :
674 0 : bool Argument::boolValue() const
675 : {
676 0 : return numberOfTimesSet();
677 : }
678 :
679 0 : unsigned int Argument::numElements() const
680 : {
681 0 : if (isNull()) {
682 0 : return 0;
683 : }
684 0 : unsigned int result = 0;
685 0 : for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
686 0 : ++result;
687 : }
688 0 : return result;
689 : }
690 :
691 0 : const char *Argument::stringValue(unsigned int idx) const
692 : {
693 0 : if (isNull() || opt->alt_type != GPGME_CONF_STRING) {
694 0 : return 0;
695 : }
696 0 : gpgme_conf_arg_t a = arg;
697 0 : while (a && idx) {
698 0 : a = a->next;
699 0 : --idx;
700 : }
701 0 : return a ? a->value.string : 0 ;
702 : }
703 :
704 0 : int Argument::intValue(unsigned int idx) const
705 : {
706 0 : if (isNull() || opt->alt_type != GPGME_CONF_INT32) {
707 0 : return 0;
708 : }
709 0 : gpgme_conf_arg_t a = arg;
710 0 : while (a && idx) {
711 0 : a = a->next;
712 0 : --idx;
713 : }
714 0 : return a ? a->value.int32 : 0 ;
715 : }
716 :
717 0 : unsigned int Argument::uintValue(unsigned int idx) const
718 : {
719 0 : if (isNull() || opt->alt_type != GPGME_CONF_UINT32) {
720 0 : return 0;
721 : }
722 0 : gpgme_conf_arg_t a = arg;
723 0 : while (a && idx) {
724 0 : a = a->next;
725 0 : --idx;
726 : }
727 0 : return a ? a->value.uint32 : 0 ;
728 : }
729 :
730 0 : unsigned int Argument::numberOfTimesSet() const
731 : {
732 0 : if (isNull() || opt->alt_type != GPGME_CONF_NONE) {
733 0 : return 0;
734 : }
735 0 : return arg->value.count;
736 : }
737 :
738 0 : std::vector<const char *> Argument::stringValues() const
739 : {
740 0 : if (isNull() || opt->alt_type != GPGME_CONF_STRING) {
741 0 : return std::vector<const char *>();
742 : }
743 0 : std::vector<const char *> result;
744 0 : for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
745 0 : result.push_back(a->value.string);
746 : }
747 0 : return result;
748 : }
749 :
750 0 : std::vector<int> Argument::intValues() const
751 : {
752 0 : if (isNull() || opt->alt_type != GPGME_CONF_INT32) {
753 0 : return std::vector<int>();
754 : }
755 0 : std::vector<int> result;
756 0 : for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
757 0 : result.push_back(a->value.int32);
758 : }
759 0 : return result;
760 : }
761 :
762 0 : std::vector<unsigned int> Argument::uintValues() const
763 : {
764 0 : if (isNull() || opt->alt_type != GPGME_CONF_UINT32) {
765 0 : return std::vector<unsigned int>();
766 : }
767 0 : std::vector<unsigned int> result;
768 0 : for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
769 0 : result.push_back(a->value.uint32);
770 : }
771 0 : return result;
772 : }
773 :
774 0 : std::ostream &Configuration::operator<<(std::ostream &os, Level level)
775 : {
776 0 : switch (level) {
777 0 : case Basic: return os << "Basic";
778 0 : case Advanced: return os << "Advanced";
779 0 : case Expert: return os << "Expert";
780 0 : case Invisible: return os << "Invisible";
781 0 : case Internal: return os << "Internal";
782 : case NumLevels: ;
783 : }
784 0 : return os << "<unknown>";
785 : }
786 :
787 0 : std::ostream &Configuration::operator<<(std::ostream &os, Type type)
788 : {
789 0 : switch (type) {
790 0 : case NoType: return os << "None";
791 0 : case StringType: return os << "String";
792 0 : case IntegerType: return os << "Integer";
793 0 : case UnsignedIntegerType: return os << "UnsignedInteger";
794 0 : case FilenameType: return os << "Filename";
795 0 : case LdapServerType: return os << "LdapServer";
796 0 : case KeyFingerprintType: return os << "KeyFingerprint";
797 0 : case PublicKeyType: return os << "PublicKey";
798 0 : case SecretKeyType: return os << "SecretKey";
799 0 : case AliasListType: return os << "AliasList";
800 : case MaxType: ;
801 : }
802 0 : return os << "<unknown>";
803 : }
804 :
805 0 : std::ostream &Configuration::operator<<(std::ostream &os, Flag f)
806 : {
807 0 : unsigned int flags = f;
808 0 : std::vector<const char *> s;
809 0 : if (flags & Group) {
810 0 : s.push_back("Group");
811 : }
812 0 : if (flags & Optional) {
813 0 : s.push_back("Optional");
814 : }
815 0 : if (flags & List) {
816 0 : s.push_back("List");
817 : }
818 0 : if (flags & Runtime) {
819 0 : s.push_back("Runtime");
820 : }
821 0 : if (flags & Default) {
822 0 : s.push_back("Default");
823 : }
824 0 : if (flags & DefaultDescription) {
825 0 : s.push_back("DefaultDescription");
826 : }
827 0 : if (flags & NoArgumentDescription) {
828 0 : s.push_back("NoArgumentDescription");
829 : }
830 0 : if (flags & NoChange) {
831 0 : s.push_back("NoChange");
832 : }
833 0 : flags &= ~(Group | Optional | List | Runtime | Default | DefaultDescription | NoArgumentDescription | NoChange);
834 0 : if (flags) {
835 0 : s.push_back("other flags(");
836 : }
837 : std::copy(s.begin(), s.end(),
838 0 : std::ostream_iterator<const char *>(os, "|"));
839 0 : if (flags) {
840 0 : os << flags << ')';
841 : }
842 0 : return os;
843 : }
844 :
845 0 : std::ostream &Configuration::operator<<(std::ostream &os, const Component &c)
846 : {
847 : os << "Component["
848 : << "\n name : " << protect(c.name())
849 : << "\n description: " << protect(c.description())
850 : << "\n programName: " << protect(c.programName())
851 0 : << "\n options : \n";
852 0 : const std::vector<Option> options = c.options();
853 : std::copy(options.begin(), options.end(),
854 0 : std::ostream_iterator<Option>(os, "\n"));
855 0 : os << "\n]";
856 0 : return os;
857 : }
858 :
859 0 : std::ostream &Configuration::operator<<(std::ostream &os, const Option &o)
860 : {
861 : return os << "Option["
862 : << "\n name: : " << protect(o.name())
863 : << "\n description : " << protect(o.description())
864 : << "\n argName : " << protect(o.argumentName())
865 0 : << "\n flags : " << static_cast<Flag>(o.flags())
866 0 : << "\n level : " << o.level()
867 0 : << "\n type : " << o.type()
868 0 : << "\n alt_type : " << o.alternateType()
869 0 : << "\n default_val : " << o.defaultValue()
870 : << "\n default_desc: " << protect(o.defaultDescription())
871 0 : << "\n no_arg_value: " << o.noArgumentValue()
872 : << "\n no_arg_desc : " << protect(o.noArgumentDescription())
873 0 : << "\n active_value: " << o.activeValue()
874 0 : << "\n new_value : " << o.newValue()
875 0 : << "\n --> cur_val : " << o.currentValue()
876 0 : << "\n set : " << o.set()
877 0 : << "\n dirty : " << o.dirty()
878 0 : << "\n]"
879 : ;
880 : }
881 :
882 0 : std::ostream &Configuration::operator<<(std::ostream &os, const Argument &a)
883 : {
884 0 : const Option o = a.parent();
885 0 : const bool list = o.flags() & List;
886 0 : os << "Argument[";
887 0 : if (a) {
888 0 : switch (o.alternateType()) {
889 : case NoType:
890 0 : if (list) {
891 0 : os << a.numberOfTimesSet() << 'x';
892 : } else {
893 0 : os << a.boolValue();
894 : }
895 0 : break;
896 : default:
897 : case StringType:
898 0 : if (list) {
899 0 : const std::vector<const char *> v = a.stringValues();
900 0 : os << v.size() << ':';
901 : // can't use std::copy + ostream_iterator here, since we need the protect() call
902 0 : bool first = true;
903 0 : std::for_each(v.begin(), v.end(), [&first, &os](const char *s) {
904 0 : if (first) {
905 0 : first = false;
906 : } else {
907 0 : os << ',';
908 : }
909 0 : os << protect(s);
910 0 : });
911 : } else {
912 0 : os << protect(a.stringValue());
913 : }
914 0 : break;
915 : case IntegerType:
916 0 : if (list) {
917 0 : const std::vector<int> v = a.intValues();
918 0 : os << v.size() << ':';
919 : std::copy(v.begin(), v.end(),
920 0 : std::ostream_iterator<int>(os, ","));
921 : } else {
922 0 : os << a.intValue();
923 : }
924 0 : break;
925 : case UnsignedIntegerType:
926 0 : if (list) {
927 0 : const std::vector<unsigned int> v = a.uintValues();
928 0 : os << v.size() << ':';
929 : std::copy(v.begin(), v.end(),
930 0 : std::ostream_iterator<unsigned int>(os, ","));
931 : } else {
932 0 : os << a.intValue();
933 : }
934 0 : break;
935 : }
936 : }
937 0 : return os << ']';
938 0 : }
|