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