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