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