~ubuntu-branches/ubuntu/vivid/wpasupplicant/vivid

« back to all changes in this revision

Viewing changes to dbus_dict_helpers.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2006-10-05 08:04:01 UTC
  • mfrom: (1.1.5 upstream) (3 etch)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20061005080401-r8lqlix4390yos7b
Tags: 0.5.5-2
* Update madwifi headers to latest SVN. (Closes: #388316)
* Remove failed attempt at action locking. [debian/functions.sh,
  debian/wpa_action.sh]
* Add hysteresis checking functions, to avoid "event loops" while
  using wpa-roam. [debian/functions.sh, debian/wpa_action.sh]
* Change of co-maintainer email address.
* Add ishex() function to functions.sh to determine wpa-psk value type in
  plaintext or hex. This effectively eliminates the need for the bogus and
  somewhat confusing wpa-passphrase contruct specific to our scripts and
  allows wpa-psk to work with either a 8 to 63 character long plaintext
  string or 64 character long hex string.
* Adjust README.modes to not refer to the redundant wpa-passphrase stuff.
* Add big fat NOTE about acceptable wpa-psk's to top of example gallery.
* Strip surrounding quotes from wpa-ssid if present, instead of just whining
  about them.
* Update email address in copyright blurb of functions.sh, ifupdown.sh and
  wpa_action.sh.  

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * WPA Supplicant / dbus-based control interface
 
3
 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License version 2 as
 
7
 * published by the Free Software Foundation.
 
8
 *
 
9
 * Alternatively, this software may be distributed under the terms of BSD
 
10
 * license.
 
11
 *
 
12
 * See README and COPYING for more details.
 
13
 */
 
14
 
 
15
#include <dbus/dbus.h>
 
16
#include <string.h>
 
17
#include <stdio.h>
 
18
#include <stdlib.h>
 
19
 
 
20
#include "common.h"
 
21
#include "dbus_dict_helpers.h"
 
22
 
 
23
 
 
24
/**
 
25
 * Start a dict in a dbus message.  Should be paired with a call to
 
26
 * {@link wpa_dbus_dict_close_write}.
 
27
 *
 
28
 * @param iter A valid dbus message iterator
 
29
 * @param iter_dict (out) A dict iterator to pass to further dict functions
 
30
 * @return TRUE on success, FALSE on failure
 
31
 *
 
32
 */
 
33
dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter,
 
34
                                     DBusMessageIter *iter_dict)
 
35
{
 
36
        dbus_bool_t result;
 
37
 
 
38
        if (!iter || !iter_dict)
 
39
                return FALSE;
 
40
 
 
41
        result = dbus_message_iter_open_container(
 
42
                iter,
 
43
                DBUS_TYPE_ARRAY,
 
44
                DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
 
45
                DBUS_TYPE_STRING_AS_STRING
 
46
                DBUS_TYPE_VARIANT_AS_STRING
 
47
                DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
 
48
                iter_dict);
 
49
        return result;
 
50
}
 
51
 
 
52
 
 
53
/**
 
54
 * End a dict element in a dbus message.  Should be paired with
 
55
 * a call to {@link wpa_dbus_dict_open_write}.
 
56
 *
 
57
 * @param iter valid dbus message iterator, same as passed to
 
58
 *    wpa_dbus_dict_open_write()
 
59
 * @param iter_dict a dbus dict iterator returned from
 
60
 *    {@link wpa_dbus_dict_open_write}
 
61
 * @return TRUE on success, FALSE on failure
 
62
 *
 
63
 */
 
64
dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter,
 
65
                                      DBusMessageIter *iter_dict)
 
66
{
 
67
        if (!iter || !iter_dict)
 
68
                return FALSE;
 
69
 
 
70
        return dbus_message_iter_close_container(iter, iter_dict);
 
71
}
 
72
 
 
73
 
 
74
static const char * _wpa_get_type_as_string_from_type(const int type)
 
75
{
 
76
        switch(type) {
 
77
        case DBUS_TYPE_BYTE:
 
78
                return DBUS_TYPE_BYTE_AS_STRING;
 
79
        case DBUS_TYPE_BOOLEAN:
 
80
                return DBUS_TYPE_BOOLEAN_AS_STRING;
 
81
        case DBUS_TYPE_INT16:
 
82
                return DBUS_TYPE_INT16_AS_STRING;
 
83
        case DBUS_TYPE_UINT16:
 
84
                return DBUS_TYPE_UINT16_AS_STRING;
 
85
        case DBUS_TYPE_INT32:
 
86
                return DBUS_TYPE_INT32_AS_STRING;
 
87
        case DBUS_TYPE_UINT32:
 
88
                return DBUS_TYPE_UINT32_AS_STRING;
 
89
        case DBUS_TYPE_INT64:
 
90
                return DBUS_TYPE_INT64_AS_STRING;
 
91
        case DBUS_TYPE_UINT64:
 
92
                return DBUS_TYPE_UINT64_AS_STRING;
 
93
        case DBUS_TYPE_DOUBLE:
 
94
                return DBUS_TYPE_DOUBLE_AS_STRING;
 
95
        case DBUS_TYPE_STRING:
 
96
                return DBUS_TYPE_STRING_AS_STRING;
 
97
        case DBUS_TYPE_OBJECT_PATH:
 
98
                return DBUS_TYPE_OBJECT_PATH_AS_STRING;
 
99
        case DBUS_TYPE_ARRAY:
 
100
                return DBUS_TYPE_ARRAY_AS_STRING;
 
101
        default:
 
102
                return NULL;
 
103
        }
 
104
}
 
105
 
 
106
 
 
107
static dbus_bool_t _wpa_dbus_add_dict_entry_start(
 
108
        DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
 
109
        const char *key, const int value_type)
 
110
{
 
111
        if (!dbus_message_iter_open_container(iter_dict,
 
112
                                              DBUS_TYPE_DICT_ENTRY, NULL,
 
113
                                              iter_dict_entry))
 
114
                return FALSE;
 
115
 
 
116
        if (!dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING,
 
117
                                            &key))
 
118
                return FALSE;
 
119
 
 
120
        return TRUE;
 
121
}
 
122
 
 
123
 
 
124
static dbus_bool_t _wpa_dbus_add_dict_entry_end(
 
125
        DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
 
126
        DBusMessageIter *iter_dict_val)
 
127
{
 
128
        if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val))
 
129
                return FALSE;
 
130
        if (!dbus_message_iter_close_container(iter_dict, iter_dict_entry))
 
131
                return FALSE;
 
132
 
 
133
        return TRUE;
 
134
}
 
135
 
 
136
 
 
137
static dbus_bool_t _wpa_dbus_add_dict_entry_basic(DBusMessageIter *iter_dict,
 
138
                                                  const char *key,
 
139
                                                  const int value_type,
 
140
                                                  const void *value)
 
141
{
 
142
        DBusMessageIter iter_dict_entry, iter_dict_val;
 
143
        const char *type_as_string = NULL;
 
144
 
 
145
        type_as_string = _wpa_get_type_as_string_from_type(value_type);
 
146
        if (!type_as_string)
 
147
                return FALSE;
 
148
 
 
149
        if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
 
150
                                            key, value_type))
 
151
                return FALSE;
 
152
 
 
153
        if (!dbus_message_iter_open_container(&iter_dict_entry,
 
154
                                              DBUS_TYPE_VARIANT,
 
155
                                              type_as_string, &iter_dict_val))
 
156
                return FALSE;
 
157
 
 
158
        if (!dbus_message_iter_append_basic(&iter_dict_val, value_type, value))
 
159
                return FALSE;
 
160
 
 
161
        if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
 
162
                                          &iter_dict_val))
 
163
                return FALSE;
 
164
 
 
165
        return TRUE;
 
166
}
 
167
 
 
168
 
 
169
static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array(
 
170
        DBusMessageIter *iter_dict, const char *key,
 
171
        const char *value, const dbus_uint32_t value_len)
 
172
{
 
173
        DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
 
174
        dbus_uint32_t i;
 
175
 
 
176
        if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
 
177
                                            key, DBUS_TYPE_ARRAY))
 
178
                return FALSE;
 
179
 
 
180
        if (!dbus_message_iter_open_container(&iter_dict_entry,
 
181
                                              DBUS_TYPE_VARIANT,
 
182
                                              DBUS_TYPE_ARRAY_AS_STRING
 
183
                                              DBUS_TYPE_BYTE_AS_STRING,
 
184
                                              &iter_dict_val))
 
185
                return FALSE;
 
186
 
 
187
        if (!dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY,
 
188
                                              DBUS_TYPE_BYTE_AS_STRING,
 
189
                                              &iter_array))
 
190
                return FALSE;
 
191
 
 
192
        for (i = 0; i < value_len; i++) {
 
193
                if (!dbus_message_iter_append_basic(&iter_array,
 
194
                                                    DBUS_TYPE_BYTE,
 
195
                                                    &(value[i])))
 
196
                        return FALSE;
 
197
        }
 
198
 
 
199
        if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array))
 
200
                return FALSE;
 
201
 
 
202
        if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
 
203
                                          &iter_dict_val))
 
204
                return FALSE;
 
205
 
 
206
        return TRUE;
 
207
}
 
208
 
 
209
 
 
210
/**
 
211
 * Add a string entry to the dict.
 
212
 *
 
213
 * @param iter_dict A valid DBusMessageIter returned from
 
214
 *    {@link wpa_dbus_dict_open_write}
 
215
 * @param key The key of the dict item
 
216
 * @param value The string value
 
217
 * @return TRUE on success, FALSE on failure
 
218
 *
 
219
 */
 
220
dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict,
 
221
                                        const char *key, const char *value)
 
222
{
 
223
        if (!key || !value)
 
224
                return FALSE;
 
225
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_STRING,
 
226
                                              &value);
 
227
}
 
228
 
 
229
 
 
230
/**
 
231
 * Add a byte entry to the dict.
 
232
 *
 
233
 * @param iter_dict A valid DBusMessageIter returned from
 
234
 *    {@link wpa_dbus_dict_open_write}
 
235
 * @param key The key of the dict item
 
236
 * @param value The byte value
 
237
 * @return TRUE on success, FALSE on failure
 
238
 *
 
239
 */
 
240
dbus_bool_t wpa_dbus_dict_append_byte(DBusMessageIter *iter_dict,
 
241
                                      const char *key, const char value)
 
242
{
 
243
        if (!key)
 
244
                return FALSE;
 
245
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_BYTE,
 
246
                                              &value);
 
247
}
 
248
 
 
249
 
 
250
/**
 
251
 * Add a boolean entry to the dict.
 
252
 *
 
253
 * @param iter_dict A valid DBusMessageIter returned from
 
254
 *    {@link wpa_dbus_dict_open_write}
 
255
 * @param key The key of the dict item
 
256
 * @param value The boolean value
 
257
 * @return TRUE on success, FALSE on failure
 
258
 *
 
259
 */
 
260
dbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict,
 
261
                                      const char *key, const dbus_bool_t value)
 
262
{
 
263
        if (!key)
 
264
                return FALSE;
 
265
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
 
266
                                              DBUS_TYPE_BOOLEAN, &value);
 
267
}
 
268
 
 
269
 
 
270
/**
 
271
 * Add a 16-bit signed integer entry to the dict.
 
272
 *
 
273
 * @param iter_dict A valid DBusMessageIter returned from
 
274
 *    {@link wpa_dbus_dict_open_write}
 
275
 * @param key The key of the dict item
 
276
 * @param value The 16-bit signed integer value
 
277
 * @return TRUE on success, FALSE on failure
 
278
 *
 
279
 */
 
280
dbus_bool_t wpa_dbus_dict_append_int16(DBusMessageIter *iter_dict,
 
281
                                       const char *key,
 
282
                                       const dbus_int16_t value)
 
283
{
 
284
        if (!key)
 
285
                return FALSE;
 
286
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT16,
 
287
                                              &value);
 
288
}
 
289
 
 
290
 
 
291
/**
 
292
 * Add a 16-bit unsigned integer entry to the dict.
 
293
 *
 
294
 * @param iter_dict A valid DBusMessageIter returned from
 
295
 *    {@link wpa_dbus_dict_open_write}
 
296
 * @param key The key of the dict item
 
297
 * @param value The 16-bit unsigned integer value
 
298
 * @return TRUE on success, FALSE on failure
 
299
 *
 
300
 */
 
301
dbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict,
 
302
                                        const char *key,
 
303
                                        const dbus_uint16_t value)
 
304
{
 
305
        if (!key)
 
306
                return FALSE;
 
307
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT16,
 
308
                                              &value);
 
309
}
 
310
 
 
311
 
 
312
/**
 
313
 * Add a 32-bit signed integer to the dict.
 
314
 *
 
315
 * @param iter_dict A valid DBusMessageIter returned from
 
316
 *    {@link wpa_dbus_dict_open_write}
 
317
 * @param key The key of the dict item
 
318
 * @param value The 32-bit signed integer value
 
319
 * @return TRUE on success, FALSE on failure
 
320
 *
 
321
 */
 
322
dbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict,
 
323
                                       const char *key,
 
324
                                       const dbus_int32_t value)
 
325
{
 
326
        if (!key)
 
327
                return FALSE;
 
328
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT32,
 
329
                                              &value);
 
330
}
 
331
 
 
332
 
 
333
/**
 
334
 * Add a 32-bit unsigned integer entry to the dict.
 
335
 *
 
336
 * @param iter_dict A valid DBusMessageIter returned from
 
337
 *    {@link wpa_dbus_dict_open_write}
 
338
 * @param key The key of the dict item
 
339
 * @param value The 32-bit unsigned integer value
 
340
 * @return TRUE on success, FALSE on failure
 
341
 *
 
342
 */
 
343
dbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict,
 
344
                                        const char *key,
 
345
                                        const dbus_uint32_t value)
 
346
{
 
347
        if (!key)
 
348
                return FALSE;
 
349
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT32,
 
350
                                              &value);
 
351
}
 
352
 
 
353
 
 
354
/**
 
355
 * Add a 64-bit integer entry to the dict.
 
356
 *
 
357
 * @param iter_dict A valid DBusMessageIter returned from
 
358
 *    {@link wpa_dbus_dict_open_write}
 
359
 * @param key The key of the dict item
 
360
 * @param value The 64-bit integer value
 
361
 * @return TRUE on success, FALSE on failure
 
362
 *
 
363
 */
 
364
dbus_bool_t wpa_dbus_dict_append_int64(DBusMessageIter *iter_dict,
 
365
                                       const char *key,
 
366
                                       const dbus_int64_t value)
 
367
{
 
368
        if (!key)
 
369
                return FALSE;
 
370
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT64,
 
371
                                              &value);
 
372
}
 
373
 
 
374
 
 
375
/**
 
376
 * Add a 64-bit unsigned integer entry to the dict.
 
377
 *
 
378
 * @param iter_dict A valid DBusMessageIter returned from
 
379
 *    {@link wpa_dbus_dict_open_write}
 
380
 * @param key The key of the dict item
 
381
 * @param value The 64-bit unsigned integer value
 
382
 * @return TRUE on success, FALSE on failure
 
383
 *
 
384
 */
 
385
dbus_bool_t wpa_dbus_dict_append_uint64(DBusMessageIter *iter_dict,
 
386
                                        const char *key,
 
387
                                        const dbus_uint64_t value)
 
388
{
 
389
        if (!key)
 
390
                return FALSE;
 
391
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT64,
 
392
                                              &value);
 
393
}
 
394
 
 
395
 
 
396
/**
 
397
 * Add a double-precision floating point entry to the dict.
 
398
 *
 
399
 * @param iter_dict A valid DBusMessageIter returned from
 
400
 *    {@link wpa_dbus_dict_open_write}
 
401
 * @param key The key of the dict item
 
402
 * @param value The double-precision floating point value
 
403
 * @return TRUE on success, FALSE on failure
 
404
 *
 
405
 */
 
406
dbus_bool_t wpa_dbus_dict_append_double(DBusMessageIter *iter_dict,
 
407
                                        const char * key,
 
408
                                        const double value)
 
409
{
 
410
        if (!key)
 
411
                return FALSE;
 
412
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_DOUBLE,
 
413
                                              &value);
 
414
}
 
415
 
 
416
 
 
417
/**
 
418
 * Add a DBus object path entry to the dict.
 
419
 *
 
420
 * @param iter_dict A valid DBusMessageIter returned from
 
421
 *    {@link wpa_dbus_dict_open_write}
 
422
 * @param key The key of the dict item
 
423
 * @param value The DBus object path value
 
424
 * @return TRUE on success, FALSE on failure
 
425
 *
 
426
 */
 
427
dbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict,
 
428
                                             const char *key,
 
429
                                             const char *value)
 
430
{
 
431
        if (!key || !value)
 
432
                return FALSE;
 
433
        return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
 
434
                                              DBUS_TYPE_OBJECT_PATH, &value);
 
435
}
 
436
 
 
437
 
 
438
/**
 
439
 * Add a byte array entry to the dict.
 
440
 *
 
441
 * @param iter_dict A valid DBusMessageIter returned from
 
442
 *    {@link wpa_dbus_dict_open_write}
 
443
 * @param key The key of the dict item
 
444
 * @param value The byte array
 
445
 * @param value_len The length of the byte array, in bytes
 
446
 * @return TRUE on success, FALSE on failure
 
447
 *
 
448
 */
 
449
dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict,
 
450
                                            const char *key,
 
451
                                            const char *value,
 
452
                                            const dbus_uint32_t value_len)
 
453
{
 
454
        if (!key)
 
455
                return FALSE;
 
456
        if (!value && (value_len != 0))
 
457
                return FALSE;
 
458
        return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value,
 
459
                                                   value_len);
 
460
}
 
461
 
 
462
 
 
463
/**
 
464
 * Begin a string array entry in the dict
 
465
 *
 
466
 * @param iter_dict A valid DBusMessageIter returned from
 
467
 *                  {@link nmu_dbus_dict_open_write}
 
468
 * @param key The key of the dict item
 
469
 * @param iter_dict_entry A private DBusMessageIter provided by the caller to
 
470
 *                        be passed to {@link wpa_dbus_dict_end_string_array}
 
471
 * @param iter_dict_val A private DBusMessageIter provided by the caller to
 
472
 *                      be passed to {@link wpa_dbus_dict_end_string_array}
 
473
 * @param iter_array On return, the DBusMessageIter to be passed to 
 
474
 *                   {@link wpa_dbus_dict_string_array_add_element}
 
475
 * @return TRUE on success, FALSE on failure
 
476
 *
 
477
 */
 
478
dbus_bool_t wpa_dbus_dict_begin_string_array(DBusMessageIter *iter_dict,
 
479
                                             const char *key,
 
480
                                             DBusMessageIter *iter_dict_entry,
 
481
                                             DBusMessageIter *iter_dict_val,
 
482
                                             DBusMessageIter *iter_array)
 
483
{
 
484
        if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array)
 
485
                return FALSE;
 
486
 
 
487
        if (!_wpa_dbus_add_dict_entry_start(iter_dict, iter_dict_entry,
 
488
                                            key, DBUS_TYPE_ARRAY))
 
489
                return FALSE;
 
490
 
 
491
        if (!dbus_message_iter_open_container(iter_dict_entry,
 
492
                                              DBUS_TYPE_VARIANT,
 
493
                                              DBUS_TYPE_ARRAY_AS_STRING
 
494
                                              DBUS_TYPE_STRING_AS_STRING,
 
495
                                              iter_dict_val))
 
496
                return FALSE;
 
497
 
 
498
        if (!dbus_message_iter_open_container(iter_dict_val, DBUS_TYPE_ARRAY,
 
499
                                              DBUS_TYPE_BYTE_AS_STRING,
 
500
                                              iter_array))
 
501
                return FALSE;
 
502
 
 
503
        return TRUE;
 
504
}
 
505
 
 
506
 
 
507
/**
 
508
 * Add a single string element to a string array dict entry
 
509
 *
 
510
 * @param iter_array A valid DBusMessageIter returned from
 
511
 *                   {@link wpa_dbus_dict_begin_string_array}'s
 
512
 *                   iter_array parameter
 
513
 * @param elem The string element to be added to the dict entry's string array
 
514
 * @return TRUE on success, FALSE on failure
 
515
 *
 
516
 */
 
517
dbus_bool_t wpa_dbus_dict_string_array_add_element(DBusMessageIter *iter_array,
 
518
                                                   const char *elem)
 
519
{
 
520
        if (!iter_array || !elem)
 
521
                return FALSE;
 
522
 
 
523
        return dbus_message_iter_append_basic(iter_array, DBUS_TYPE_STRING,
 
524
                                              &elem);
 
525
}
 
526
 
 
527
 
 
528
/**
 
529
 * End a string array dict entry
 
530
 *
 
531
 * @param iter_dict A valid DBusMessageIter returned from
 
532
 *                  {@link nmu_dbus_dict_open_write}
 
533
 * @param iter_dict_entry A private DBusMessageIter returned from
 
534
 *                        {@link wpa_dbus_dict_end_string_array}
 
535
 * @param iter_dict_val A private DBusMessageIter returned from
 
536
 *                      {@link wpa_dbus_dict_end_string_array}
 
537
 * @param iter_array A DBusMessageIter returned from
 
538
 *                   {@link wpa_dbus_dict_end_string_array}
 
539
 * @return TRUE on success, FALSE on failure
 
540
 *
 
541
 */
 
542
dbus_bool_t wpa_dbus_dict_end_string_array(DBusMessageIter *iter_dict,
 
543
                                           DBusMessageIter *iter_dict_entry,
 
544
                                           DBusMessageIter *iter_dict_val,
 
545
                                           DBusMessageIter *iter_array)
 
546
{
 
547
        if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array)
 
548
                return FALSE;
 
549
 
 
550
        if (!dbus_message_iter_close_container(iter_dict_val, iter_array))
 
551
                return FALSE;
 
552
 
 
553
        if (!_wpa_dbus_add_dict_entry_end(iter_dict, iter_dict_entry,
 
554
                                          iter_dict_val))
 
555
                return FALSE;
 
556
 
 
557
        return TRUE;
 
558
}
 
559
 
 
560
 
 
561
/**
 
562
 * Convenience function to add an entire string array to the dict.
 
563
 *
 
564
 * @param iter_dict A valid DBusMessageIter returned from
 
565
 *                  {@link nmu_dbus_dict_open_write}
 
566
 * @param key The key of the dict item
 
567
 * @param items The array of strings
 
568
 * @param num_items The number of strings in the array
 
569
 * @return TRUE on success, FALSE on failure
 
570
 *
 
571
 */
 
572
dbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict,
 
573
                                              const char *key,
 
574
                                              const char **items,
 
575
                                              const dbus_uint32_t num_items)
 
576
{
 
577
        DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
 
578
        dbus_uint32_t i;
 
579
 
 
580
        if (!key)
 
581
                return FALSE;
 
582
        if (!items && (num_items != 0))
 
583
                return FALSE;
 
584
 
 
585
        if (!wpa_dbus_dict_begin_string_array(iter_dict, key,
 
586
                                              &iter_dict_entry, &iter_dict_val,
 
587
                                              &iter_array))
 
588
                return FALSE;
 
589
 
 
590
        for (i = 0; i < num_items; i++) {
 
591
                if (!wpa_dbus_dict_string_array_add_element(&iter_array,
 
592
                                                            items[i]))
 
593
                        return FALSE;
 
594
        }
 
595
 
 
596
        if (!wpa_dbus_dict_end_string_array(iter_dict, &iter_dict_entry,
 
597
                                            &iter_dict_val, &iter_array))
 
598
                return FALSE;
 
599
 
 
600
        return TRUE;
 
601
}
 
602
 
 
603
 
 
604
/*****************************************************/
 
605
/* Stuff for reading dicts                           */
 
606
/*****************************************************/
 
607
 
 
608
/**
 
609
 * Start reading from a dbus dict.
 
610
 *
 
611
 * @param iter A valid DBusMessageIter pointing to the start of the dict
 
612
 * @param iter_dict (out) A DBusMessageIter to be passed to
 
613
 *    {@link wpa_dbus_dict_read_next_entry}
 
614
 * @return TRUE on success, FALSE on failure
 
615
 *
 
616
 */
 
617
dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
 
618
                                    DBusMessageIter *iter_dict)
 
619
{
 
620
        if (!iter || !iter_dict)
 
621
                return FALSE;
 
622
 
 
623
        if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
 
624
            dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY)
 
625
                return FALSE;
 
626
 
 
627
        dbus_message_iter_recurse(iter, iter_dict);
 
628
        return TRUE;
 
629
}
 
630
 
 
631
 
 
632
static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array(
 
633
        DBusMessageIter *iter, int array_len, int array_type,
 
634
        struct wpa_dbus_dict_entry *entry)
 
635
{
 
636
        dbus_uint32_t i = 0;
 
637
        dbus_bool_t success = FALSE;
 
638
        char byte;
 
639
 
 
640
        /* Zero-length arrays are valid. */
 
641
        if (array_len == 0) {
 
642
                entry->bytearray_value = NULL;
 
643
                entry->array_type = DBUS_TYPE_BYTE;
 
644
                success = TRUE;
 
645
                goto done;
 
646
        }
 
647
 
 
648
        entry->bytearray_value = wpa_zalloc(array_len * sizeof(char));
 
649
        if (!entry->bytearray_value) {
 
650
                perror("_wpa_dbus_dict_entry_get_byte_array[dbus]: out of "
 
651
                       "memory");
 
652
                goto done;
 
653
        }
 
654
 
 
655
        entry->array_type = DBUS_TYPE_BYTE;
 
656
        entry->array_len = array_len;
 
657
        while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) {
 
658
                dbus_message_iter_get_basic(iter, &byte);
 
659
                entry->bytearray_value[i++] = byte;
 
660
                dbus_message_iter_next(iter);
 
661
        }
 
662
        success = TRUE;
 
663
 
 
664
done:
 
665
        return success;
 
666
}
 
667
 
 
668
 
 
669
static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
 
670
        DBusMessageIter *iter, int array_len, int array_type,
 
671
        struct wpa_dbus_dict_entry *entry)
 
672
{
 
673
        dbus_uint32_t count = 0;
 
674
        dbus_bool_t success = FALSE;
 
675
        char **buffer;
 
676
 
 
677
        entry->strarray_value = NULL;
 
678
        entry->array_type = DBUS_TYPE_STRING;
 
679
 
 
680
        /* Zero-length arrays are valid. */
 
681
        if (array_len == 0) {
 
682
                success = TRUE;
 
683
                goto done;
 
684
        }
 
685
 
 
686
        buffer = wpa_zalloc(sizeof (char *) * 8);
 
687
        if (buffer == NULL) {
 
688
                perror("_wpa_dbus_dict_entry_get_string_array[dbus] out of "
 
689
                       "memory trying to retrieve a string array");
 
690
                goto done;
 
691
        }
 
692
 
 
693
        entry->strarray_value = buffer;
 
694
        entry->array_len = 0;
 
695
        while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
 
696
                const char *value;
 
697
                char *str;
 
698
 
 
699
                if ((count % 8) == 0 && count != 0) {
 
700
                        char **tmp;
 
701
                        tmp = realloc(buffer, sizeof(char *) * (count + 8));
 
702
                        if (tmp == NULL) {
 
703
                                perror("_wpa_dbus_dict_entry_get_string_array["
 
704
                                       "dbus] out of memory trying to "
 
705
                                       "retrieve the string array");
 
706
                                free(buffer);
 
707
                                buffer = NULL;
 
708
                                goto done;
 
709
                        }
 
710
                        buffer = tmp;
 
711
                }
 
712
                entry->strarray_value = buffer;
 
713
 
 
714
                dbus_message_iter_get_basic(iter, &value);
 
715
                str = strdup(value);
 
716
                if (str == NULL) {
 
717
                        perror("_wpa_dbus_dict_entry_get_string_array[dbus] "
 
718
                               "out of memory trying to duplicate the string "
 
719
                               "array");
 
720
                        goto done;
 
721
                }
 
722
                entry->strarray_value[count] = str;
 
723
                entry->array_len = ++count;
 
724
                dbus_message_iter_next(iter);
 
725
        }
 
726
        success = TRUE;
 
727
 
 
728
done:
 
729
        return success;
 
730
}
 
731
 
 
732
 
 
733
static dbus_bool_t _wpa_dbus_dict_entry_get_array(
 
734
        DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry)
 
735
{
 
736
        int array_type = dbus_message_iter_get_element_type(iter_dict_val);
 
737
        int array_len;
 
738
        dbus_bool_t success = FALSE;
 
739
        DBusMessageIter iter_array;
 
740
 
 
741
        if (!entry)
 
742
                return FALSE;
 
743
 
 
744
        dbus_message_iter_recurse(iter_dict_val, &iter_array);
 
745
 
 
746
        array_len = dbus_message_iter_get_array_len(&iter_array);
 
747
        if (array_len < 0)
 
748
                return FALSE;
 
749
 
 
750
        switch (array_type) {
 
751
        case DBUS_TYPE_BYTE:
 
752
                success = _wpa_dbus_dict_entry_get_byte_array(&iter_array,
 
753
                                                              array_len,
 
754
                                                              array_type,
 
755
                                                              entry);
 
756
                break;
 
757
        case DBUS_TYPE_STRING:
 
758
                success = _wpa_dbus_dict_entry_get_string_array(&iter_array,
 
759
                                                                array_len,
 
760
                                                                array_type,
 
761
                                                                entry);
 
762
                break;
 
763
        default:
 
764
                break;
 
765
        }
 
766
 
 
767
        return success;
 
768
}
 
769
 
 
770
 
 
771
static dbus_bool_t _wpa_dbus_dict_fill_value_from_variant(
 
772
        struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter_dict_val)
 
773
{
 
774
        dbus_bool_t success = TRUE;
 
775
 
 
776
        switch (entry->type) {
 
777
        case DBUS_TYPE_STRING: {
 
778
                const char *v;
 
779
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
780
                entry->str_value = strdup(v);
 
781
                break;
 
782
        }
 
783
        case DBUS_TYPE_BOOLEAN: {
 
784
                dbus_bool_t v;
 
785
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
786
                entry->bool_value = v;
 
787
                break;
 
788
        }
 
789
        case DBUS_TYPE_BYTE: {
 
790
                char v;
 
791
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
792
                entry->byte_value = v;
 
793
                break;
 
794
        }
 
795
        case DBUS_TYPE_INT16: {
 
796
                dbus_int16_t v;
 
797
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
798
                entry->int16_value = v;
 
799
                break;
 
800
        }
 
801
        case DBUS_TYPE_UINT16: {
 
802
                dbus_uint16_t v;
 
803
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
804
                entry->uint16_value = v;
 
805
                break;
 
806
        }
 
807
        case DBUS_TYPE_INT32: {
 
808
                dbus_int32_t v;
 
809
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
810
                entry->int32_value = v;
 
811
                break;
 
812
        }
 
813
        case DBUS_TYPE_UINT32: {
 
814
                dbus_uint32_t v;
 
815
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
816
                entry->uint32_value = v;
 
817
                break;
 
818
        }
 
819
        case DBUS_TYPE_INT64: {
 
820
                dbus_int64_t v;
 
821
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
822
                entry->int64_value = v;
 
823
                break;
 
824
        }
 
825
        case DBUS_TYPE_UINT64: {
 
826
                dbus_uint64_t v;
 
827
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
828
                entry->uint64_value = v;
 
829
                break;
 
830
        }
 
831
        case DBUS_TYPE_DOUBLE: {
 
832
                double v;
 
833
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
834
                entry->double_value = v;
 
835
                break;
 
836
        }
 
837
        case DBUS_TYPE_OBJECT_PATH: {
 
838
                char *v;
 
839
                dbus_message_iter_get_basic(iter_dict_val, &v);
 
840
                entry->str_value = strdup(v);
 
841
                break;
 
842
        }
 
843
        case DBUS_TYPE_ARRAY: {
 
844
                success = _wpa_dbus_dict_entry_get_array(iter_dict_val, entry);
 
845
                break;
 
846
        }
 
847
        default:
 
848
                success = FALSE;
 
849
                break;
 
850
        }
 
851
 
 
852
        return success;
 
853
}
 
854
 
 
855
 
 
856
/**
 
857
 * Read the current key/value entry from the dict.  Entries are dynamically
 
858
 * allocated when needed and must be freed after use with the
 
859
 * {@link wpa_dbus_dict_entry_clear} function.
 
860
 *
 
861
 * The returned entry object will be filled with the type and value of the next
 
862
 * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error
 
863
 * occurred.
 
864
 *
 
865
 * @param iter_dict A valid DBusMessageIter returned from
 
866
 *    {@link wpa_dbus_dict_open_read}
 
867
 * @param entry A valid dict entry object into which the dict key and value
 
868
 *    will be placed
 
869
 * @return TRUE on success, FALSE on failure
 
870
 *
 
871
 */
 
872
dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
 
873
                                    struct wpa_dbus_dict_entry * entry)
 
874
{
 
875
        DBusMessageIter iter_dict_entry, iter_dict_val;
 
876
        int type;
 
877
        const char *key;
 
878
 
 
879
        if (!iter_dict || !entry)
 
880
                goto error;
 
881
 
 
882
        if (dbus_message_iter_get_arg_type(iter_dict) != DBUS_TYPE_DICT_ENTRY)
 
883
                goto error;
 
884
 
 
885
        dbus_message_iter_recurse(iter_dict, &iter_dict_entry);
 
886
        dbus_message_iter_get_basic(&iter_dict_entry, &key);
 
887
        entry->key = key;
 
888
 
 
889
        if (!dbus_message_iter_next(&iter_dict_entry))
 
890
                goto error;
 
891
        type = dbus_message_iter_get_arg_type(&iter_dict_entry);
 
892
        if (type != DBUS_TYPE_VARIANT)
 
893
                goto error;
 
894
 
 
895
        dbus_message_iter_recurse(&iter_dict_entry, &iter_dict_val);
 
896
        entry->type = dbus_message_iter_get_arg_type(&iter_dict_val);
 
897
        if (!_wpa_dbus_dict_fill_value_from_variant(entry, &iter_dict_val))
 
898
                goto error;
 
899
 
 
900
        dbus_message_iter_next(iter_dict);
 
901
        return TRUE;
 
902
 
 
903
error:
 
904
        wpa_dbus_dict_entry_clear(entry);
 
905
        entry->type = DBUS_TYPE_INVALID;
 
906
        entry->array_type = DBUS_TYPE_INVALID;
 
907
        return FALSE;
 
908
}
 
909
 
 
910
 
 
911
/**
 
912
 * Return whether or not there are additional dictionary entries.
 
913
 *
 
914
 * @param iter_dict A valid DBusMessageIter returned from
 
915
 *    {@link wpa_dbus_dict_open_read}
 
916
 * @return TRUE if more dict entries exists, FALSE if no more dict entries
 
917
 * exist
 
918
 */
 
919
dbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict)
 
920
{
 
921
        if (!iter_dict) {
 
922
                perror("wpa_dbus_dict_has_dict_entry[dbus]: out of memory");
 
923
                return FALSE;
 
924
        }
 
925
        return dbus_message_iter_get_arg_type(iter_dict) ==
 
926
                DBUS_TYPE_DICT_ENTRY;
 
927
}
 
928
 
 
929
 
 
930
/**
 
931
 * Free any memory used by the entry object.
 
932
 *
 
933
 * @param entry The entry object
 
934
 */
 
935
void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry)
 
936
{
 
937
        if (!entry)
 
938
                return;
 
939
        switch (entry->type) {
 
940
        case DBUS_TYPE_OBJECT_PATH:
 
941
        case DBUS_TYPE_STRING:
 
942
                free(entry->str_value);
 
943
                break;
 
944
        case DBUS_TYPE_ARRAY:
 
945
                switch (entry->array_type) {
 
946
                case DBUS_TYPE_BYTE:
 
947
                        free(entry->bytearray_value);
 
948
                        break;
 
949
                }
 
950
                break;
 
951
        }
 
952
 
 
953
        memset(entry, 0, sizeof(struct wpa_dbus_dict_entry));
 
954
}