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-internals.h"
00027 #include "dbus-sysdeps.h"
00028 #include "dbus-threads.h"
00029 #include "dbus-protocol.h"
00030 #include "dbus-string.h"
00031 #include "dbus-list.h"
00032 #include "dbus-misc.h"
00033
00034
00035
00036
00037
00038
00039 #if HAVE_LOCALE_H
00040 #include <locale.h>
00041 #endif
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <stdio.h>
00045
00046 #ifdef HAVE_ERRNO_H
00047 #include <errno.h>
00048 #endif
00049
00050 #ifdef DBUS_WIN
00051 #include <stdlib.h>
00052 #elif (defined __APPLE__)
00053 # include <crt_externs.h>
00054 # define environ (*_NSGetEnviron())
00055 #else
00056 extern char **environ;
00057 #endif
00058
00076 void
00077 _dbus_abort (void)
00078 {
00079 const char *s;
00080
00081 _dbus_print_backtrace ();
00082
00083 s = _dbus_getenv ("DBUS_BLOCK_ON_ABORT");
00084 if (s && *s)
00085 {
00086
00087 fprintf (stderr, " Process %lu sleeping for gdb attach\n", _dbus_pid_for_log ());
00088 _dbus_sleep_milliseconds (1000 * 180);
00089 }
00090
00091 abort ();
00092 _dbus_exit (1);
00093 }
00094
00113 dbus_bool_t
00114 dbus_setenv (const char *varname,
00115 const char *value)
00116 {
00117 _dbus_assert (varname != NULL);
00118
00119 if (value == NULL)
00120 {
00121 #ifdef HAVE_UNSETENV
00122 unsetenv (varname);
00123 return TRUE;
00124 #else
00125 char *putenv_value;
00126 size_t len;
00127
00128 len = strlen (varname);
00129
00130
00131
00132
00133
00134 putenv_value = malloc (len + 2);
00135 if (putenv_value == NULL)
00136 return FALSE;
00137
00138 strcpy (putenv_value, varname);
00139 #if defined(DBUS_WIN)
00140 strcat (putenv_value, "=");
00141 #endif
00142
00143 return (putenv (putenv_value) == 0);
00144 #endif
00145 }
00146 else
00147 {
00148 #ifdef HAVE_SETENV
00149 return (setenv (varname, value, TRUE) == 0);
00150 #else
00151 char *putenv_value;
00152 size_t len;
00153 size_t varname_len;
00154 size_t value_len;
00155
00156 varname_len = strlen (varname);
00157 value_len = strlen (value);
00158
00159 len = varname_len + value_len + 1 ;
00160
00161
00162
00163
00164
00165 putenv_value = malloc (len + 1);
00166 if (putenv_value == NULL)
00167 return FALSE;
00168
00169 strcpy (putenv_value, varname);
00170 strcpy (putenv_value + varname_len, "=");
00171 strcpy (putenv_value + varname_len + 1, value);
00172
00173 return (putenv (putenv_value) == 0);
00174 #endif
00175 }
00176 }
00177
00184 const char*
00185 _dbus_getenv (const char *varname)
00186 {
00187
00188
00189
00190 if (_dbus_check_setuid ())
00191 return NULL;
00192 return getenv (varname);
00193 }
00194
00200 dbus_bool_t
00201 _dbus_clearenv (void)
00202 {
00203 dbus_bool_t rc = TRUE;
00204
00205 #ifdef HAVE_CLEARENV
00206 if (clearenv () != 0)
00207 rc = FALSE;
00208 #else
00209
00210 if (environ != NULL)
00211 environ[0] = NULL;
00212 #endif
00213
00214 return rc;
00215 }
00216
00225 dbus_bool_t
00226 _dbus_split_paths_and_append (DBusString *dirs,
00227 const char *suffix,
00228 DBusList **dir_list)
00229 {
00230 int start;
00231 int i;
00232 int len;
00233 char *cpath;
00234 DBusString file_suffix;
00235
00236 start = 0;
00237 i = 0;
00238
00239 _dbus_string_init_const (&file_suffix, suffix);
00240
00241 len = _dbus_string_get_length (dirs);
00242
00243 while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i))
00244 {
00245 DBusString path;
00246
00247 if (!_dbus_string_init (&path))
00248 goto oom;
00249
00250 if (!_dbus_string_copy_len (dirs,
00251 start,
00252 i - start,
00253 &path,
00254 0))
00255 {
00256 _dbus_string_free (&path);
00257 goto oom;
00258 }
00259
00260 _dbus_string_chop_white (&path);
00261
00262
00263 if (_dbus_string_get_length (&path) == 0)
00264 goto next;
00265
00266 if (!_dbus_concat_dir_and_file (&path,
00267 &file_suffix))
00268 {
00269 _dbus_string_free (&path);
00270 goto oom;
00271 }
00272
00273 if (!_dbus_string_copy_data(&path, &cpath))
00274 {
00275 _dbus_string_free (&path);
00276 goto oom;
00277 }
00278
00279 if (!_dbus_list_append (dir_list, cpath))
00280 {
00281 _dbus_string_free (&path);
00282 dbus_free (cpath);
00283 goto oom;
00284 }
00285
00286 next:
00287 _dbus_string_free (&path);
00288 start = i + 1;
00289 }
00290
00291 if (start != len)
00292 {
00293 DBusString path;
00294
00295 if (!_dbus_string_init (&path))
00296 goto oom;
00297
00298 if (!_dbus_string_copy_len (dirs,
00299 start,
00300 len - start,
00301 &path,
00302 0))
00303 {
00304 _dbus_string_free (&path);
00305 goto oom;
00306 }
00307
00308 if (!_dbus_concat_dir_and_file (&path,
00309 &file_suffix))
00310 {
00311 _dbus_string_free (&path);
00312 goto oom;
00313 }
00314
00315 if (!_dbus_string_copy_data(&path, &cpath))
00316 {
00317 _dbus_string_free (&path);
00318 goto oom;
00319 }
00320
00321 if (!_dbus_list_append (dir_list, cpath))
00322 {
00323 _dbus_string_free (&path);
00324 dbus_free (cpath);
00325 goto oom;
00326 }
00327
00328 _dbus_string_free (&path);
00329 }
00330
00331 return TRUE;
00332
00333 oom:
00334 _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL);
00335 _dbus_list_clear (dir_list);
00336 return FALSE;
00337 }
00338
00353 dbus_bool_t
00354 _dbus_string_append_int (DBusString *str,
00355 long value)
00356 {
00357
00358 #define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1)
00359 int orig_len;
00360 int i;
00361 char *buf;
00362
00363 orig_len = _dbus_string_get_length (str);
00364
00365 if (!_dbus_string_lengthen (str, MAX_LONG_LEN))
00366 return FALSE;
00367
00368 buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN);
00369
00370 snprintf (buf, MAX_LONG_LEN, "%ld", value);
00371
00372 i = 0;
00373 while (*buf)
00374 {
00375 ++buf;
00376 ++i;
00377 }
00378
00379 _dbus_string_shorten (str, MAX_LONG_LEN - i);
00380
00381 return TRUE;
00382 }
00383
00391 dbus_bool_t
00392 _dbus_string_append_uint (DBusString *str,
00393 unsigned long value)
00394 {
00395
00396 #define MAX_ULONG_LEN (MAX_LONG_LEN * 2)
00397 int orig_len;
00398 int i;
00399 char *buf;
00400
00401 orig_len = _dbus_string_get_length (str);
00402
00403 if (!_dbus_string_lengthen (str, MAX_ULONG_LEN))
00404 return FALSE;
00405
00406 buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN);
00407
00408 snprintf (buf, MAX_ULONG_LEN, "%lu", value);
00409
00410 i = 0;
00411 while (*buf)
00412 {
00413 ++buf;
00414 ++i;
00415 }
00416
00417 _dbus_string_shorten (str, MAX_ULONG_LEN - i);
00418
00419 return TRUE;
00420 }
00421
00434 dbus_bool_t
00435 _dbus_string_parse_int (const DBusString *str,
00436 int start,
00437 long *value_return,
00438 int *end_return)
00439 {
00440 long v;
00441 const char *p;
00442 char *end;
00443
00444 p = _dbus_string_get_const_data_len (str, start,
00445 _dbus_string_get_length (str) - start);
00446
00447 end = NULL;
00448 _dbus_set_errno_to_zero ();
00449 v = strtol (p, &end, 0);
00450 if (end == NULL || end == p || errno != 0)
00451 return FALSE;
00452
00453 if (value_return)
00454 *value_return = v;
00455 if (end_return)
00456 *end_return = start + (end - p);
00457
00458 return TRUE;
00459 }
00460
00473 dbus_bool_t
00474 _dbus_string_parse_uint (const DBusString *str,
00475 int start,
00476 unsigned long *value_return,
00477 int *end_return)
00478 {
00479 unsigned long v;
00480 const char *p;
00481 char *end;
00482
00483 p = _dbus_string_get_const_data_len (str, start,
00484 _dbus_string_get_length (str) - start);
00485
00486 end = NULL;
00487 _dbus_set_errno_to_zero ();
00488 v = strtoul (p, &end, 0);
00489 if (end == NULL || end == p || errno != 0)
00490 return FALSE;
00491
00492 if (value_return)
00493 *value_return = v;
00494 if (end_return)
00495 *end_return = start + (end - p);
00496
00497 return TRUE;
00498 }
00499
00501
00515 dbus_bool_t
00516 _dbus_generate_random_bytes_buffer (char *buffer,
00517 int n_bytes,
00518 DBusError *error)
00519 {
00520 DBusString str;
00521
00522 if (!_dbus_string_init (&str))
00523 {
00524 _DBUS_SET_OOM (error);
00525 return FALSE;
00526 }
00527
00528 if (!_dbus_generate_random_bytes (&str, n_bytes, error))
00529 {
00530 _dbus_string_free (&str);
00531 return FALSE;
00532 }
00533
00534 _dbus_string_copy_to_buffer (&str, buffer, n_bytes);
00535
00536 _dbus_string_free (&str);
00537 return TRUE;
00538 }
00539
00549 dbus_bool_t
00550 _dbus_generate_random_ascii (DBusString *str,
00551 int n_bytes,
00552 DBusError *error)
00553 {
00554 static const char letters[] =
00555 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
00556 int i;
00557 int len;
00558
00559 if (!_dbus_generate_random_bytes (str, n_bytes, error))
00560 return FALSE;
00561
00562 len = _dbus_string_get_length (str);
00563 i = len - n_bytes;
00564 while (i < len)
00565 {
00566 _dbus_string_set_byte (str, i,
00567 letters[_dbus_string_get_byte (str, i) %
00568 (sizeof (letters) - 1)]);
00569
00570 ++i;
00571 }
00572
00573 _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
00574 n_bytes));
00575
00576 return TRUE;
00577 }
00578
00589 const char*
00590 _dbus_error_from_errno (int error_number)
00591 {
00592 switch (error_number)
00593 {
00594 case 0:
00595 return DBUS_ERROR_FAILED;
00596
00597 #ifdef EPROTONOSUPPORT
00598 case EPROTONOSUPPORT:
00599 return DBUS_ERROR_NOT_SUPPORTED;
00600 #elif defined(WSAEPROTONOSUPPORT)
00601 case WSAEPROTONOSUPPORT:
00602 return DBUS_ERROR_NOT_SUPPORTED;
00603 #endif
00604 #ifdef EAFNOSUPPORT
00605 case EAFNOSUPPORT:
00606 return DBUS_ERROR_NOT_SUPPORTED;
00607 #elif defined(WSAEAFNOSUPPORT)
00608 case WSAEAFNOSUPPORT:
00609 return DBUS_ERROR_NOT_SUPPORTED;
00610 #endif
00611 #ifdef ENFILE
00612 case ENFILE:
00613 return DBUS_ERROR_LIMITS_EXCEEDED;
00614 #endif
00615 #ifdef EMFILE
00616 case EMFILE:
00617 return DBUS_ERROR_LIMITS_EXCEEDED;
00618 #endif
00619 #ifdef EACCES
00620 case EACCES:
00621 return DBUS_ERROR_ACCESS_DENIED;
00622 #endif
00623 #ifdef EPERM
00624 case EPERM:
00625 return DBUS_ERROR_ACCESS_DENIED;
00626 #endif
00627 #ifdef ENOBUFS
00628 case ENOBUFS:
00629 return DBUS_ERROR_NO_MEMORY;
00630 #endif
00631 #ifdef ENOMEM
00632 case ENOMEM:
00633 return DBUS_ERROR_NO_MEMORY;
00634 #endif
00635 #ifdef ECONNREFUSED
00636 case ECONNREFUSED:
00637 return DBUS_ERROR_NO_SERVER;
00638 #elif defined(WSAECONNREFUSED)
00639 case WSAECONNREFUSED:
00640 return DBUS_ERROR_NO_SERVER;
00641 #endif
00642 #ifdef ETIMEDOUT
00643 case ETIMEDOUT:
00644 return DBUS_ERROR_TIMEOUT;
00645 #elif defined(WSAETIMEDOUT)
00646 case WSAETIMEDOUT:
00647 return DBUS_ERROR_TIMEOUT;
00648 #endif
00649 #ifdef ENETUNREACH
00650 case ENETUNREACH:
00651 return DBUS_ERROR_NO_NETWORK;
00652 #elif defined(WSAENETUNREACH)
00653 case WSAENETUNREACH:
00654 return DBUS_ERROR_NO_NETWORK;
00655 #endif
00656 #ifdef EADDRINUSE
00657 case EADDRINUSE:
00658 return DBUS_ERROR_ADDRESS_IN_USE;
00659 #elif defined(WSAEADDRINUSE)
00660 case WSAEADDRINUSE:
00661 return DBUS_ERROR_ADDRESS_IN_USE;
00662 #endif
00663 #ifdef EEXIST
00664 case EEXIST:
00665 return DBUS_ERROR_FILE_EXISTS;
00666 #endif
00667 #ifdef ENOENT
00668 case ENOENT:
00669 return DBUS_ERROR_FILE_NOT_FOUND;
00670 #endif
00671 }
00672
00673 return DBUS_ERROR_FAILED;
00674 }
00675
00681 const char*
00682 _dbus_error_from_system_errno (void)
00683 {
00684 return _dbus_error_from_errno (errno);
00685 }
00686
00690 void
00691 _dbus_set_errno_to_zero (void)
00692 {
00693 #ifdef DBUS_WINCE
00694 SetLastError (0);
00695 #else
00696 errno = 0;
00697 #endif
00698 }
00699
00704 dbus_bool_t
00705 _dbus_get_is_errno_enomem (int e)
00706 {
00707 return e == ENOMEM;
00708 }
00709
00714 dbus_bool_t
00715 _dbus_get_is_errno_eintr (int e)
00716 {
00717 return e == EINTR;
00718 }
00719
00724 dbus_bool_t
00725 _dbus_get_is_errno_epipe (int e)
00726 {
00727 return e == EPIPE;
00728 }
00729
00734 dbus_bool_t
00735 _dbus_get_is_errno_etoomanyrefs (int e)
00736 {
00737 #ifdef ETOOMANYREFS
00738 return e == ETOOMANYREFS;
00739 #else
00740 return FALSE;
00741 #endif
00742 }
00743
00748 const char*
00749 _dbus_strerror_from_errno (void)
00750 {
00751 return _dbus_strerror (errno);
00752 }
00753
00756