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