Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

dbus-address.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */ 00002 /* dbus-address.c Server address parser. 00003 * 00004 * Copyright (C) 2003 CodeFactory AB 00005 * Copyright (C) 2004 Red Hat, Inc. 00006 * 00007 * Licensed under the Academic Free License version 2.1 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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 /* End of internals */ 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 /* Append the entry */ 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 /* Look for a semi-colon */ 00226 if (!_dbus_string_find (&str, pos, ";", &end_pos)) 00227 end_pos = len; 00228 00229 /* Look for the colon : */ 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 /* End of public API */ 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 /* Different possible errors */ 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

Generated on Tue Oct 12 02:07:52 2004 for D-BUS by doxygen 1.3.7