00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-address.h"
00026 #include "dbus-internals.h"
00027 #include "dbus-list.h"
00028 #include "dbus-string.h"
00029
00041 struct DBusAddressEntry
00042 {
00043 DBusString method;
00045 DBusList *keys;
00046 DBusList *values;
00047 };
00048
00050
00051 static void
00052 dbus_address_entry_free (DBusAddressEntry *entry)
00053 {
00054 DBusList *link;
00055
00056 _dbus_string_free (&entry->method);
00057
00058 link = _dbus_list_get_first_link (&entry->keys);
00059 while (link != NULL)
00060 {
00061 _dbus_string_free (link->data);
00062 dbus_free (link->data);
00063
00064 link = _dbus_list_get_next_link (&entry->keys, link);
00065 }
00066 _dbus_list_clear (&entry->keys);
00067
00068 link = _dbus_list_get_first_link (&entry->values);
00069 while (link != NULL)
00070 {
00071 _dbus_string_free (link->data);
00072 dbus_free (link->data);
00073
00074 link = _dbus_list_get_next_link (&entry->values, link);
00075 }
00076 _dbus_list_clear (&entry->values);
00077
00078 dbus_free (entry);
00079 }
00080
00094 void
00095 dbus_address_entries_free (DBusAddressEntry **entries)
00096 {
00097 int i;
00098
00099 for (i = 0; entries[i] != NULL; i++)
00100 dbus_address_entry_free (entries[i]);
00101 dbus_free (entries);
00102 }
00103
00104 static DBusAddressEntry *
00105 create_entry (void)
00106 {
00107 DBusAddressEntry *entry;
00108
00109 entry = dbus_new0 (DBusAddressEntry, 1);
00110
00111 if (entry == NULL)
00112 return NULL;
00113
00114 if (!_dbus_string_init (&entry->method))
00115 {
00116 dbus_free (entry);
00117 return NULL;
00118 }
00119
00120 return entry;
00121 }
00122
00130 const char *
00131 dbus_address_entry_get_method (DBusAddressEntry *entry)
00132 {
00133 return _dbus_string_get_const_data (&entry->method);
00134 }
00135
00143 const char *
00144 dbus_address_entry_get_value (DBusAddressEntry *entry,
00145 const char *key)
00146 {
00147 DBusList *values, *keys;
00148
00149 keys = _dbus_list_get_first_link (&entry->keys);
00150 values = _dbus_list_get_first_link (&entry->values);
00151
00152 while (keys != NULL)
00153 {
00154 _dbus_assert (values != NULL);
00155
00156 if (_dbus_string_equal_c_str (keys->data, key))
00157 return _dbus_string_get_const_data (values->data);
00158
00159 keys = _dbus_list_get_next_link (&entry->keys, keys);
00160 values = _dbus_list_get_next_link (&entry->values, values);
00161 }
00162
00163 return NULL;
00164 }
00165
00182 dbus_bool_t
00183 dbus_parse_address (const char *address,
00184 DBusAddressEntry ***entry,
00185 int *array_len,
00186 DBusError *error)
00187 {
00188 DBusString str;
00189 int pos, end_pos, len, i;
00190 DBusList *entries, *link;
00191 DBusAddressEntry **entry_array;
00192
00193 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00194
00195 _dbus_string_init_const (&str, address);
00196
00197 entries = NULL;
00198 pos = 0;
00199 len = _dbus_string_get_length (&str);
00200
00201 while (pos < len)
00202 {
00203 DBusAddressEntry *entry;
00204
00205 int found_pos;
00206
00207 entry = create_entry ();
00208 if (!entry)
00209 {
00210 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00211
00212 goto error;
00213 }
00214
00215
00216 if (!_dbus_list_append (&entries, entry))
00217 {
00218 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00219 dbus_address_entry_free (entry);
00220 goto error;
00221 }
00222
00223
00224 if (!_dbus_string_find (&str, pos, ";", &end_pos))
00225 end_pos = len;
00226
00227
00228 if (!_dbus_string_find_to (&str, pos, end_pos, ":", &found_pos))
00229 {
00230 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, "Address does not contain a colon");
00231 goto error;
00232 }
00233
00234 if (!_dbus_string_copy_len (&str, pos, found_pos - pos, &entry->method, 0))
00235 {
00236 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00237 goto error;
00238 }
00239
00240 pos = found_pos + 1;
00241
00242 while (pos < end_pos)
00243 {
00244 int comma_pos, equals_pos;
00245
00246 if (!_dbus_string_find_to (&str, pos, end_pos, ",", &comma_pos))
00247 comma_pos = end_pos;
00248
00249 if (!_dbus_string_find_to (&str, pos, comma_pos, "=", &equals_pos) ||
00250 equals_pos == pos || equals_pos + 1 == comma_pos)
00251 {
00252 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00253 "'=' character not found or has no value following it");
00254 goto error;
00255 }
00256 else
00257 {
00258 DBusString *key;
00259 DBusString *value;
00260
00261 key = dbus_new0 (DBusString, 1);
00262
00263 if (!key)
00264 {
00265 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00266 goto error;
00267 }
00268
00269 value = dbus_new0 (DBusString, 1);
00270 if (!value)
00271 {
00272 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00273 dbus_free (key);
00274 goto error;
00275 }
00276
00277 if (!_dbus_string_init (key))
00278 {
00279 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00280 dbus_free (key);
00281 dbus_free (value);
00282
00283 goto error;
00284 }
00285
00286 if (!_dbus_string_init (value))
00287 {
00288 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00289 _dbus_string_free (key);
00290
00291 dbus_free (key);
00292 dbus_free (value);
00293 goto error;
00294 }
00295
00296 if (!_dbus_string_copy_len (&str, pos, equals_pos - pos, key, 0))
00297 {
00298 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00299 _dbus_string_free (key);
00300 _dbus_string_free (value);
00301
00302 dbus_free (key);
00303 dbus_free (value);
00304 goto error;
00305 }
00306
00307 if (!_dbus_string_copy_len (&str, equals_pos + 1, comma_pos - equals_pos - 1, value, 0))
00308 {
00309 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00310 _dbus_string_free (key);
00311 _dbus_string_free (value);
00312
00313 dbus_free (key);
00314 dbus_free (value);
00315 goto error;
00316 }
00317
00318 if (!_dbus_list_append (&entry->keys, key))
00319 {
00320 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00321 _dbus_string_free (key);
00322 _dbus_string_free (value);
00323
00324 dbus_free (key);
00325 dbus_free (value);
00326 goto error;
00327 }
00328
00329 if (!_dbus_list_append (&entry->values, value))
00330 {
00331 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00332 _dbus_string_free (value);
00333
00334 dbus_free (value);
00335 goto error;
00336 }
00337 }
00338
00339 pos = comma_pos + 1;
00340 }
00341
00342 pos = end_pos + 1;
00343 }
00344
00345 *array_len = _dbus_list_get_length (&entries);
00346
00347 entry_array = dbus_new (DBusAddressEntry *, *array_len + 1);
00348
00349 if (!entry_array)
00350 {
00351 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00352
00353 goto error;
00354 }
00355
00356 entry_array [*array_len] = NULL;
00357
00358 link = _dbus_list_get_first_link (&entries);
00359 i = 0;
00360 while (link != NULL)
00361 {
00362 entry_array[i] = link->data;
00363 i++;
00364 link = _dbus_list_get_next_link (&entries, link);
00365 }
00366
00367 _dbus_list_clear (&entries);
00368 *entry = entry_array;
00369
00370 return TRUE;
00371
00372 error:
00373
00374 link = _dbus_list_get_first_link (&entries);
00375 while (link != NULL)
00376 {
00377 dbus_address_entry_free (link->data);
00378 link = _dbus_list_get_next_link (&entries, link);
00379 }
00380
00381 _dbus_list_clear (&entries);
00382
00383 return FALSE;
00384
00385 }
00386
00387
00389
00390 #ifdef DBUS_BUILD_TESTS
00391 #include "dbus-test.h"
00392
00393 dbus_bool_t
00394 _dbus_address_test (void)
00395 {
00396 DBusAddressEntry **entries;
00397 int len;
00398 DBusError error;
00399
00400 dbus_error_init (&error);
00401
00402 if (!dbus_parse_address ("unix:path=/tmp/foo;debug:name=test,sliff=sloff;",
00403 &entries, &len, &error))
00404 _dbus_assert_not_reached ("could not parse address");
00405 _dbus_assert (len == 2);
00406 _dbus_assert (strcmp (dbus_address_entry_get_value (entries[0], "path"), "/tmp/foo") == 0);
00407 _dbus_assert (strcmp (dbus_address_entry_get_value (entries[1], "name"), "test") == 0);
00408 _dbus_assert (strcmp (dbus_address_entry_get_value (entries[1], "sliff"), "sloff") == 0);
00409
00410 dbus_address_entries_free (entries);
00411
00412
00413 if (dbus_parse_address ("foo", &entries, &len, &error))
00414 _dbus_assert_not_reached ("Parsed incorrect address.");
00415 else
00416 dbus_error_free (&error);
00417
00418 if (dbus_parse_address ("foo:bar", &entries, &len, &error))
00419 _dbus_assert_not_reached ("Parsed incorrect address.");
00420 else
00421 dbus_error_free (&error);
00422
00423 if (dbus_parse_address ("foo:bar,baz", &entries, &len, &error))
00424 _dbus_assert_not_reached ("Parsed incorrect address.");
00425 else
00426 dbus_error_free (&error);
00427
00428 if (dbus_parse_address ("foo:bar=foo,baz", &entries, &len, &error))
00429 _dbus_assert_not_reached ("Parsed incorrect address.");
00430 else
00431 dbus_error_free (&error);
00432
00433 if (dbus_parse_address ("foo:bar=foo;baz", &entries, &len, &error))
00434 _dbus_assert_not_reached ("Parsed incorrect address.");
00435 else
00436 dbus_error_free (&error);
00437
00438 if (dbus_parse_address ("foo:=foo", &entries, &len, &error))
00439 _dbus_assert_not_reached ("Parsed incorrect address.");
00440 else
00441 dbus_error_free (&error);
00442
00443 if (dbus_parse_address ("foo:foo=", &entries, &len, &error))
00444 _dbus_assert_not_reached ("Parsed incorrect address.");
00445 else
00446 dbus_error_free (&error);
00447
00448 if (dbus_parse_address ("foo:foo,bar=baz", &entries, &len, &error))
00449 _dbus_assert_not_reached ("Parsed incorrect address.");
00450 else
00451 dbus_error_free (&error);
00452
00453 return TRUE;
00454 }
00455
00456 #endif