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 "dbus-internals.h"
00026 #include "dbus-sysdeps.h"
00027 #include "dbus-threads.h"
00028 #include "dbus-protocol.h"
00029 #include "dbus-string.h"
00030 #include "dbus-list.h"
00031
00032
00033
00034
00035
00036
00037 #include <locale.h>
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include <stdio.h>
00041
00042
00043
00044
00045
00046 #ifdef HAVE_ERRNO_H
00047 #include <errno.h>
00048 #endif
00049
00050 _DBUS_DEFINE_GLOBAL_LOCK (win_fds);
00051 _DBUS_DEFINE_GLOBAL_LOCK (sid_atom_cache);
00052 _DBUS_DEFINE_GLOBAL_LOCK (system_users);
00053
00071 void
00072 _dbus_abort (void)
00073 {
00074 const char *s;
00075
00076 _dbus_print_backtrace ();
00077
00078 s = _dbus_getenv ("DBUS_BLOCK_ON_ABORT");
00079 if (s && *s)
00080 {
00081
00082 fprintf (stderr, " Process %lu sleeping for gdb attach\n", _dbus_pid_for_log ());
00083 _dbus_sleep_milliseconds (1000 * 180);
00084 }
00085
00086 abort ();
00087 _dbus_exit (1);
00088 }
00089
00103 dbus_bool_t
00104 _dbus_setenv (const char *varname,
00105 const char *value)
00106 {
00107 _dbus_assert (varname != NULL);
00108
00109 if (value == NULL)
00110 {
00111 #ifdef HAVE_UNSETENV
00112 unsetenv (varname);
00113 return TRUE;
00114 #else
00115 char *putenv_value;
00116 size_t len;
00117
00118 len = strlen (varname);
00119
00120
00121
00122
00123
00124 putenv_value = malloc (len + 2);
00125 if (putenv_value == NULL)
00126 return FALSE;
00127
00128 strcpy (putenv_value, varname);
00129 #if defined(DBUS_WIN)
00130 strcat (putenv_value, "=");
00131 #endif
00132
00133 return (putenv (putenv_value) == 0);
00134 #endif
00135 }
00136 else
00137 {
00138 #ifdef HAVE_SETENV
00139 return (setenv (varname, value, TRUE) == 0);
00140 #else
00141 char *putenv_value;
00142 size_t len;
00143 size_t varname_len;
00144 size_t value_len;
00145
00146 varname_len = strlen (varname);
00147 value_len = strlen (value);
00148
00149 len = varname_len + value_len + 1 ;
00150
00151
00152
00153
00154
00155 putenv_value = malloc (len + 1);
00156 if (putenv_value == NULL)
00157 return FALSE;
00158
00159 strcpy (putenv_value, varname);
00160 strcpy (putenv_value + varname_len, "=");
00161 strcpy (putenv_value + varname_len + 1, value);
00162
00163 return (putenv (putenv_value) == 0);
00164 #endif
00165 }
00166 }
00167
00174 const char*
00175 _dbus_getenv (const char *varname)
00176 {
00177 return getenv (varname);
00178 }
00179
00185 dbus_bool_t
00186 _dbus_clearenv (void)
00187 {
00188 dbus_bool_t rc = TRUE;
00189
00190 #ifdef HAVE_CLEARENV
00191 if (clearenv () != 0)
00192 rc = FALSE;
00193 #else
00194 extern char **environ;
00195
00196 if (environ != NULL)
00197 environ[0] = NULL;
00198 #endif
00199
00200 return rc;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209 void
00210 _dbus_pipe_init (DBusPipe *pipe,
00211 int fd)
00212 {
00213 pipe->fd_or_handle = fd;
00214 }
00215
00221 void
00222 _dbus_pipe_init_stdout (DBusPipe *pipe)
00223 {
00224 _dbus_pipe_init (pipe, 1);
00225 }
00226
00234 dbus_bool_t
00235 _dbus_pipe_is_valid(DBusPipe *pipe)
00236 {
00237 return pipe->fd_or_handle >= 0;
00238 }
00239
00246 dbus_bool_t
00247 _dbus_pipe_is_stdout_or_stderr (DBusPipe *pipe)
00248 {
00249 return pipe->fd_or_handle == 1 || pipe->fd_or_handle == 2;
00250 }
00251
00256 void
00257 _dbus_pipe_invalidate (DBusPipe *pipe)
00258 {
00259 pipe->fd_or_handle = -1;
00260 }
00261
00270 dbus_bool_t
00271 _dbus_split_paths_and_append (DBusString *dirs,
00272 const char *suffix,
00273 DBusList **dir_list)
00274 {
00275 int start;
00276 int i;
00277 int len;
00278 char *cpath;
00279 DBusString file_suffix;
00280
00281 start = 0;
00282 i = 0;
00283
00284 _dbus_string_init_const (&file_suffix, suffix);
00285
00286 len = _dbus_string_get_length (dirs);
00287
00288 while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i))
00289 {
00290 DBusString path;
00291
00292 if (!_dbus_string_init (&path))
00293 goto oom;
00294
00295 if (!_dbus_string_copy_len (dirs,
00296 start,
00297 i - start,
00298 &path,
00299 0))
00300 {
00301 _dbus_string_free (&path);
00302 goto oom;
00303 }
00304
00305 _dbus_string_chop_white (&path);
00306
00307
00308 if (_dbus_string_get_length (&path) == 0)
00309 goto next;
00310
00311 if (!_dbus_concat_dir_and_file (&path,
00312 &file_suffix))
00313 {
00314 _dbus_string_free (&path);
00315 goto oom;
00316 }
00317
00318 if (!_dbus_string_copy_data(&path, &cpath))
00319 {
00320 _dbus_string_free (&path);
00321 goto oom;
00322 }
00323
00324 if (!_dbus_list_append (dir_list, cpath))
00325 {
00326 _dbus_string_free (&path);
00327 dbus_free (cpath);
00328 goto oom;
00329 }
00330
00331 next:
00332 _dbus_string_free (&path);
00333 start = i + 1;
00334 }
00335
00336 if (start != len)
00337 {
00338 DBusString path;
00339
00340 if (!_dbus_string_init (&path))
00341 goto oom;
00342
00343 if (!_dbus_string_copy_len (dirs,
00344 start,
00345 len - start,
00346 &path,
00347 0))
00348 {
00349 _dbus_string_free (&path);
00350 goto oom;
00351 }
00352
00353 if (!_dbus_concat_dir_and_file (&path,
00354 &file_suffix))
00355 {
00356 _dbus_string_free (&path);
00357 goto oom;
00358 }
00359
00360 if (!_dbus_string_copy_data(&path, &cpath))
00361 {
00362 _dbus_string_free (&path);
00363 goto oom;
00364 }
00365
00366 if (!_dbus_list_append (dir_list, cpath))
00367 {
00368 _dbus_string_free (&path);
00369 dbus_free (cpath);
00370 goto oom;
00371 }
00372
00373 _dbus_string_free (&path);
00374 }
00375
00376 return TRUE;
00377
00378 oom:
00379 _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL);
00380 _dbus_list_clear (dir_list);
00381 return FALSE;
00382 }
00383
00398 dbus_bool_t
00399 _dbus_string_append_int (DBusString *str,
00400 long value)
00401 {
00402
00403 #define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1)
00404 int orig_len;
00405 int i;
00406 char *buf;
00407
00408 orig_len = _dbus_string_get_length (str);
00409
00410 if (!_dbus_string_lengthen (str, MAX_LONG_LEN))
00411 return FALSE;
00412
00413 buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN);
00414
00415 snprintf (buf, MAX_LONG_LEN, "%ld", value);
00416
00417 i = 0;
00418 while (*buf)
00419 {
00420 ++buf;
00421 ++i;
00422 }
00423
00424 _dbus_string_shorten (str, MAX_LONG_LEN - i);
00425
00426 return TRUE;
00427 }
00428
00436 dbus_bool_t
00437 _dbus_string_append_uint (DBusString *str,
00438 unsigned long value)
00439 {
00440
00441 #define MAX_ULONG_LEN (MAX_LONG_LEN * 2)
00442 int orig_len;
00443 int i;
00444 char *buf;
00445
00446 orig_len = _dbus_string_get_length (str);
00447
00448 if (!_dbus_string_lengthen (str, MAX_ULONG_LEN))
00449 return FALSE;
00450
00451 buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN);
00452
00453 snprintf (buf, MAX_ULONG_LEN, "%lu", value);
00454
00455 i = 0;
00456 while (*buf)
00457 {
00458 ++buf;
00459 ++i;
00460 }
00461
00462 _dbus_string_shorten (str, MAX_ULONG_LEN - i);
00463
00464 return TRUE;
00465 }
00466
00467 #ifdef DBUS_BUILD_TESTS
00468
00475 dbus_bool_t
00476 _dbus_string_append_double (DBusString *str,
00477 double value)
00478 {
00479 #define MAX_DOUBLE_LEN 64
00480 int orig_len;
00481 char *buf;
00482 int i;
00483
00484 orig_len = _dbus_string_get_length (str);
00485
00486 if (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN))
00487 return FALSE;
00488
00489 buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN);
00490
00491 snprintf (buf, MAX_LONG_LEN, "%g", value);
00492
00493 i = 0;
00494 while (*buf)
00495 {
00496 ++buf;
00497 ++i;
00498 }
00499
00500 _dbus_string_shorten (str, MAX_DOUBLE_LEN - i);
00501
00502 return TRUE;
00503 }
00504 #endif
00505
00518 dbus_bool_t
00519 _dbus_string_parse_int (const DBusString *str,
00520 int start,
00521 long *value_return,
00522 int *end_return)
00523 {
00524 long v;
00525 const char *p;
00526 char *end;
00527
00528 p = _dbus_string_get_const_data_len (str, start,
00529 _dbus_string_get_length (str) - start);
00530
00531 end = NULL;
00532 errno = 0;
00533 v = strtol (p, &end, 0);
00534 if (end == NULL || end == p || errno != 0)
00535 return FALSE;
00536
00537 if (value_return)
00538 *value_return = v;
00539 if (end_return)
00540 *end_return = start + (end - p);
00541
00542 return TRUE;
00543 }
00544
00557 dbus_bool_t
00558 _dbus_string_parse_uint (const DBusString *str,
00559 int start,
00560 unsigned long *value_return,
00561 int *end_return)
00562 {
00563 unsigned long v;
00564 const char *p;
00565 char *end;
00566
00567 p = _dbus_string_get_const_data_len (str, start,
00568 _dbus_string_get_length (str) - start);
00569
00570 end = NULL;
00571 errno = 0;
00572 v = strtoul (p, &end, 0);
00573 if (end == NULL || end == p || errno != 0)
00574 return FALSE;
00575
00576 if (value_return)
00577 *value_return = v;
00578 if (end_return)
00579 *end_return = start + (end - p);
00580
00581 return TRUE;
00582 }
00583
00584 #ifdef DBUS_BUILD_TESTS
00585 static dbus_bool_t
00586 ascii_isspace (char c)
00587 {
00588 return (c == ' ' ||
00589 c == '\f' ||
00590 c == '\n' ||
00591 c == '\r' ||
00592 c == '\t' ||
00593 c == '\v');
00594 }
00595 #endif
00596
00597 #ifdef DBUS_BUILD_TESTS
00598 static dbus_bool_t
00599 ascii_isdigit (char c)
00600 {
00601 return c >= '0' && c <= '9';
00602 }
00603 #endif
00604
00605 #ifdef DBUS_BUILD_TESTS
00606 static dbus_bool_t
00607 ascii_isxdigit (char c)
00608 {
00609 return (ascii_isdigit (c) ||
00610 (c >= 'a' && c <= 'f') ||
00611 (c >= 'A' && c <= 'F'));
00612 }
00613 #endif
00614
00615 #ifdef DBUS_BUILD_TESTS
00616
00617
00618
00619
00620
00621 static double
00622 ascii_strtod (const char *nptr,
00623 char **endptr)
00624 {
00625
00626
00627
00628
00629 char *fail_pos;
00630 double val;
00631 struct lconv *locale_data;
00632 const char *decimal_point;
00633 int decimal_point_len;
00634 const char *p, *decimal_point_pos;
00635 const char *end = NULL;
00636
00637 fail_pos = NULL;
00638
00639 locale_data = localeconv ();
00640 decimal_point = locale_data->decimal_point;
00641 decimal_point_len = strlen (decimal_point);
00642
00643 _dbus_assert (decimal_point_len != 0);
00644
00645 decimal_point_pos = NULL;
00646 if (decimal_point[0] != '.' ||
00647 decimal_point[1] != 0)
00648 {
00649 p = nptr;
00650
00651 while (ascii_isspace (*p))
00652 p++;
00653
00654
00655 if (*p == '+' || *p == '-')
00656 p++;
00657
00658 if (p[0] == '0' &&
00659 (p[1] == 'x' || p[1] == 'X'))
00660 {
00661 p += 2;
00662
00663
00664 while (ascii_isxdigit (*p))
00665 p++;
00666
00667 if (*p == '.')
00668 {
00669 decimal_point_pos = p++;
00670
00671 while (ascii_isxdigit (*p))
00672 p++;
00673
00674 if (*p == 'p' || *p == 'P')
00675 p++;
00676 if (*p == '+' || *p == '-')
00677 p++;
00678 while (ascii_isdigit (*p))
00679 p++;
00680 end = p;
00681 }
00682 }
00683 else
00684 {
00685 while (ascii_isdigit (*p))
00686 p++;
00687
00688 if (*p == '.')
00689 {
00690 decimal_point_pos = p++;
00691
00692 while (ascii_isdigit (*p))
00693 p++;
00694
00695 if (*p == 'e' || *p == 'E')
00696 p++;
00697 if (*p == '+' || *p == '-')
00698 p++;
00699 while (ascii_isdigit (*p))
00700 p++;
00701 end = p;
00702 }
00703 }
00704
00705 }
00706
00707
00708
00709 errno = 0;
00710
00711 if (decimal_point_pos)
00712 {
00713 char *copy, *c;
00714
00715
00716 copy = dbus_malloc (end - nptr + 1 + decimal_point_len);
00717
00718 c = copy;
00719 memcpy (c, nptr, decimal_point_pos - nptr);
00720 c += decimal_point_pos - nptr;
00721 memcpy (c, decimal_point, decimal_point_len);
00722 c += decimal_point_len;
00723 memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
00724 c += end - (decimal_point_pos + 1);
00725 *c = 0;
00726
00727 val = strtod (copy, &fail_pos);
00728
00729 if (fail_pos)
00730 {
00731 if (fail_pos > decimal_point_pos)
00732 fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
00733 else
00734 fail_pos = (char *)nptr + (fail_pos - copy);
00735 }
00736
00737 dbus_free (copy);
00738
00739 }
00740 else
00741 val = strtod (nptr, &fail_pos);
00742
00743 if (endptr)
00744 *endptr = fail_pos;
00745
00746 return val;
00747 }
00748 #endif
00749
00750 #ifdef DBUS_BUILD_TESTS
00751
00763 dbus_bool_t
00764 _dbus_string_parse_double (const DBusString *str,
00765 int start,
00766 double *value_return,
00767 int *end_return)
00768 {
00769 double v;
00770 const char *p;
00771 char *end;
00772
00773 p = _dbus_string_get_const_data_len (str, start,
00774 _dbus_string_get_length (str) - start);
00775
00776
00777
00778
00779 if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
00780 return FALSE;
00781
00782 end = NULL;
00783 errno = 0;
00784 v = ascii_strtod (p, &end);
00785 if (end == NULL || end == p || errno != 0)
00786 return FALSE;
00787
00788 if (value_return)
00789 *value_return = v;
00790 if (end_return)
00791 *end_return = start + (end - p);
00792
00793 return TRUE;
00794 }
00795 #endif
00796
00798
00804 void
00805 _dbus_generate_pseudorandom_bytes_buffer (char *buffer,
00806 int n_bytes)
00807 {
00808 long tv_usec;
00809 int i;
00810
00811
00812 _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
00813 n_bytes);
00814
00815 _dbus_get_current_time (NULL, &tv_usec);
00816 srand (tv_usec);
00817
00818 i = 0;
00819 while (i < n_bytes)
00820 {
00821 double r;
00822 unsigned int b;
00823
00824 r = rand ();
00825 b = (r / (double) RAND_MAX) * 255.0;
00826
00827 buffer[i] = b;
00828
00829 ++i;
00830 }
00831 }
00832
00839 void
00840 _dbus_generate_random_bytes_buffer (char *buffer,
00841 int n_bytes)
00842 {
00843 DBusString str;
00844
00845 if (!_dbus_string_init (&str))
00846 {
00847 _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
00848 return;
00849 }
00850
00851 if (!_dbus_generate_random_bytes (&str, n_bytes))
00852 {
00853 _dbus_string_free (&str);
00854 _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
00855 return;
00856 }
00857
00858 _dbus_string_copy_to_buffer (&str, buffer, n_bytes);
00859
00860 _dbus_string_free (&str);
00861 }
00862
00871 dbus_bool_t
00872 _dbus_generate_random_ascii (DBusString *str,
00873 int n_bytes)
00874 {
00875 static const char letters[] =
00876 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
00877 int i;
00878 int len;
00879
00880 if (!_dbus_generate_random_bytes (str, n_bytes))
00881 return FALSE;
00882
00883 len = _dbus_string_get_length (str);
00884 i = len - n_bytes;
00885 while (i < len)
00886 {
00887 _dbus_string_set_byte (str, i,
00888 letters[_dbus_string_get_byte (str, i) %
00889 (sizeof (letters) - 1)]);
00890
00891 ++i;
00892 }
00893
00894 _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
00895 n_bytes));
00896
00897 return TRUE;
00898 }
00899
00910 const char*
00911 _dbus_error_from_errno (int error_number)
00912 {
00913 switch (error_number)
00914 {
00915 case 0:
00916 return DBUS_ERROR_FAILED;
00917
00918 #ifdef EPROTONOSUPPORT
00919 case EPROTONOSUPPORT:
00920 return DBUS_ERROR_NOT_SUPPORTED;
00921 #endif
00922 #ifdef EAFNOSUPPORT
00923 case EAFNOSUPPORT:
00924 return DBUS_ERROR_NOT_SUPPORTED;
00925 #endif
00926 #ifdef ENFILE
00927 case ENFILE:
00928 return DBUS_ERROR_LIMITS_EXCEEDED;
00929 #endif
00930 #ifdef EMFILE
00931 case EMFILE:
00932 return DBUS_ERROR_LIMITS_EXCEEDED;
00933 #endif
00934 #ifdef EACCES
00935 case EACCES:
00936 return DBUS_ERROR_ACCESS_DENIED;
00937 #endif
00938 #ifdef EPERM
00939 case EPERM:
00940 return DBUS_ERROR_ACCESS_DENIED;
00941 #endif
00942 #ifdef ENOBUFS
00943 case ENOBUFS:
00944 return DBUS_ERROR_NO_MEMORY;
00945 #endif
00946 #ifdef ENOMEM
00947 case ENOMEM:
00948 return DBUS_ERROR_NO_MEMORY;
00949 #endif
00950 #ifdef EINVAL
00951 case EINVAL:
00952 return DBUS_ERROR_FAILED;
00953 #endif
00954 #ifdef EBADF
00955 case EBADF:
00956 return DBUS_ERROR_FAILED;
00957 #endif
00958 #ifdef EFAULT
00959 case EFAULT:
00960 return DBUS_ERROR_FAILED;
00961 #endif
00962 #ifdef ENOTSOCK
00963 case ENOTSOCK:
00964 return DBUS_ERROR_FAILED;
00965 #endif
00966 #ifdef EISCONN
00967 case EISCONN:
00968 return DBUS_ERROR_FAILED;
00969 #endif
00970 #ifdef ECONNREFUSED
00971 case ECONNREFUSED:
00972 return DBUS_ERROR_NO_SERVER;
00973 #endif
00974 #ifdef ETIMEDOUT
00975 case ETIMEDOUT:
00976 return DBUS_ERROR_TIMEOUT;
00977 #endif
00978 #ifdef ENETUNREACH
00979 case ENETUNREACH:
00980 return DBUS_ERROR_NO_NETWORK;
00981 #endif
00982 #ifdef EADDRINUSE
00983 case EADDRINUSE:
00984 return DBUS_ERROR_ADDRESS_IN_USE;
00985 #endif
00986 #ifdef EEXIST
00987 case EEXIST:
00988 return DBUS_ERROR_FILE_EXISTS;
00989 #endif
00990 #ifdef ENOENT
00991 case ENOENT:
00992 return DBUS_ERROR_FILE_NOT_FOUND;
00993 #endif
00994 }
00995
00996 return DBUS_ERROR_FAILED;
00997 }
00998
01002 void
01003 _dbus_set_errno_to_zero (void)
01004 {
01005 errno = 0;
01006 }
01007
01012 dbus_bool_t
01013 _dbus_get_is_errno_nonzero (void)
01014 {
01015 return errno != 0;
01016 }
01017
01022 dbus_bool_t
01023 _dbus_get_is_errno_enomem (void)
01024 {
01025 return errno == ENOMEM;
01026 }
01027
01032 dbus_bool_t
01033 _dbus_get_is_errno_eintr (void)
01034 {
01035 return errno == EINTR;
01036 }
01037
01042 const char*
01043 _dbus_strerror_from_errno (void)
01044 {
01045 return _dbus_strerror (errno);
01046 }
01047
01050