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
00180
00181
00182
00183
00184
00185
00186 void
00187 _dbus_pipe_init (DBusPipe *pipe,
00188 int fd)
00189 {
00190 pipe->fd_or_handle = fd;
00191 }
00192
00198 void
00199 _dbus_pipe_init_stdout (DBusPipe *pipe)
00200 {
00201 _dbus_pipe_init (pipe, 1);
00202 }
00203
00211 dbus_bool_t
00212 _dbus_pipe_is_valid(DBusPipe *pipe)
00213 {
00214 return pipe->fd_or_handle >= 0;
00215 }
00216
00223 dbus_bool_t
00224 _dbus_pipe_is_stdout_or_stderr (DBusPipe *pipe)
00225 {
00226 return pipe->fd_or_handle == 1 || pipe->fd_or_handle == 2;
00227 }
00228
00233 void
00234 _dbus_pipe_invalidate (DBusPipe *pipe)
00235 {
00236 pipe->fd_or_handle = -1;
00237 }
00238
00247 dbus_bool_t
00248 _dbus_split_paths_and_append (DBusString *dirs,
00249 const char *suffix,
00250 DBusList **dir_list)
00251 {
00252 int start;
00253 int i;
00254 int len;
00255 char *cpath;
00256 DBusString file_suffix;
00257
00258 start = 0;
00259 i = 0;
00260
00261 _dbus_string_init_const (&file_suffix, suffix);
00262
00263 len = _dbus_string_get_length (dirs);
00264
00265 while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i))
00266 {
00267 DBusString path;
00268
00269 if (!_dbus_string_init (&path))
00270 goto oom;
00271
00272 if (!_dbus_string_copy_len (dirs,
00273 start,
00274 i - start,
00275 &path,
00276 0))
00277 {
00278 _dbus_string_free (&path);
00279 goto oom;
00280 }
00281
00282 _dbus_string_chop_white (&path);
00283
00284
00285 if (_dbus_string_get_length (&path) == 0)
00286 goto next;
00287
00288 if (!_dbus_concat_dir_and_file (&path,
00289 &file_suffix))
00290 {
00291 _dbus_string_free (&path);
00292 goto oom;
00293 }
00294
00295 if (!_dbus_string_copy_data(&path, &cpath))
00296 {
00297 _dbus_string_free (&path);
00298 goto oom;
00299 }
00300
00301 if (!_dbus_list_append (dir_list, cpath))
00302 {
00303 _dbus_string_free (&path);
00304 dbus_free (cpath);
00305 goto oom;
00306 }
00307
00308 next:
00309 _dbus_string_free (&path);
00310 start = i + 1;
00311 }
00312
00313 if (start != len)
00314 {
00315 DBusString path;
00316
00317 if (!_dbus_string_init (&path))
00318 goto oom;
00319
00320 if (!_dbus_string_copy_len (dirs,
00321 start,
00322 len - start,
00323 &path,
00324 0))
00325 {
00326 _dbus_string_free (&path);
00327 goto oom;
00328 }
00329
00330 if (!_dbus_concat_dir_and_file (&path,
00331 &file_suffix))
00332 {
00333 _dbus_string_free (&path);
00334 goto oom;
00335 }
00336
00337 if (!_dbus_string_copy_data(&path, &cpath))
00338 {
00339 _dbus_string_free (&path);
00340 goto oom;
00341 }
00342
00343 if (!_dbus_list_append (dir_list, cpath))
00344 {
00345 _dbus_string_free (&path);
00346 dbus_free (cpath);
00347 goto oom;
00348 }
00349
00350 _dbus_string_free (&path);
00351 }
00352
00353 return TRUE;
00354
00355 oom:
00356 _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL);
00357 _dbus_list_clear (dir_list);
00358 return FALSE;
00359 }
00360
00375 dbus_bool_t
00376 _dbus_string_append_int (DBusString *str,
00377 long value)
00378 {
00379
00380 #define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1)
00381 int orig_len;
00382 int i;
00383 char *buf;
00384
00385 orig_len = _dbus_string_get_length (str);
00386
00387 if (!_dbus_string_lengthen (str, MAX_LONG_LEN))
00388 return FALSE;
00389
00390 buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN);
00391
00392 snprintf (buf, MAX_LONG_LEN, "%ld", value);
00393
00394 i = 0;
00395 while (*buf)
00396 {
00397 ++buf;
00398 ++i;
00399 }
00400
00401 _dbus_string_shorten (str, MAX_LONG_LEN - i);
00402
00403 return TRUE;
00404 }
00405
00413 dbus_bool_t
00414 _dbus_string_append_uint (DBusString *str,
00415 unsigned long value)
00416 {
00417
00418 #define MAX_ULONG_LEN (MAX_LONG_LEN * 2)
00419 int orig_len;
00420 int i;
00421 char *buf;
00422
00423 orig_len = _dbus_string_get_length (str);
00424
00425 if (!_dbus_string_lengthen (str, MAX_ULONG_LEN))
00426 return FALSE;
00427
00428 buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN);
00429
00430 snprintf (buf, MAX_ULONG_LEN, "%lu", value);
00431
00432 i = 0;
00433 while (*buf)
00434 {
00435 ++buf;
00436 ++i;
00437 }
00438
00439 _dbus_string_shorten (str, MAX_ULONG_LEN - i);
00440
00441 return TRUE;
00442 }
00443
00444 #ifdef DBUS_BUILD_TESTS
00445
00452 dbus_bool_t
00453 _dbus_string_append_double (DBusString *str,
00454 double value)
00455 {
00456 #define MAX_DOUBLE_LEN 64
00457 int orig_len;
00458 char *buf;
00459 int i;
00460
00461 orig_len = _dbus_string_get_length (str);
00462
00463 if (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN))
00464 return FALSE;
00465
00466 buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN);
00467
00468 snprintf (buf, MAX_LONG_LEN, "%g", value);
00469
00470 i = 0;
00471 while (*buf)
00472 {
00473 ++buf;
00474 ++i;
00475 }
00476
00477 _dbus_string_shorten (str, MAX_DOUBLE_LEN - i);
00478
00479 return TRUE;
00480 }
00481 #endif
00482
00495 dbus_bool_t
00496 _dbus_string_parse_int (const DBusString *str,
00497 int start,
00498 long *value_return,
00499 int *end_return)
00500 {
00501 long v;
00502 const char *p;
00503 char *end;
00504
00505 p = _dbus_string_get_const_data_len (str, start,
00506 _dbus_string_get_length (str) - start);
00507
00508 end = NULL;
00509 errno = 0;
00510 v = strtol (p, &end, 0);
00511 if (end == NULL || end == p || errno != 0)
00512 return FALSE;
00513
00514 if (value_return)
00515 *value_return = v;
00516 if (end_return)
00517 *end_return = start + (end - p);
00518
00519 return TRUE;
00520 }
00521
00534 dbus_bool_t
00535 _dbus_string_parse_uint (const DBusString *str,
00536 int start,
00537 unsigned long *value_return,
00538 int *end_return)
00539 {
00540 unsigned long v;
00541 const char *p;
00542 char *end;
00543
00544 p = _dbus_string_get_const_data_len (str, start,
00545 _dbus_string_get_length (str) - start);
00546
00547 end = NULL;
00548 errno = 0;
00549 v = strtoul (p, &end, 0);
00550 if (end == NULL || end == p || errno != 0)
00551 return FALSE;
00552
00553 if (value_return)
00554 *value_return = v;
00555 if (end_return)
00556 *end_return = start + (end - p);
00557
00558 return TRUE;
00559 }
00560
00561 #ifdef DBUS_BUILD_TESTS
00562 static dbus_bool_t
00563 ascii_isspace (char c)
00564 {
00565 return (c == ' ' ||
00566 c == '\f' ||
00567 c == '\n' ||
00568 c == '\r' ||
00569 c == '\t' ||
00570 c == '\v');
00571 }
00572 #endif
00573
00574 #ifdef DBUS_BUILD_TESTS
00575 static dbus_bool_t
00576 ascii_isdigit (char c)
00577 {
00578 return c >= '0' && c <= '9';
00579 }
00580 #endif
00581
00582 #ifdef DBUS_BUILD_TESTS
00583 static dbus_bool_t
00584 ascii_isxdigit (char c)
00585 {
00586 return (ascii_isdigit (c) ||
00587 (c >= 'a' && c <= 'f') ||
00588 (c >= 'A' && c <= 'F'));
00589 }
00590 #endif
00591
00592 #ifdef DBUS_BUILD_TESTS
00593
00594
00595
00596
00597
00598 static double
00599 ascii_strtod (const char *nptr,
00600 char **endptr)
00601 {
00602
00603
00604
00605
00606 char *fail_pos;
00607 double val;
00608 struct lconv *locale_data;
00609 const char *decimal_point;
00610 int decimal_point_len;
00611 const char *p, *decimal_point_pos;
00612 const char *end = NULL;
00613
00614 fail_pos = NULL;
00615
00616 locale_data = localeconv ();
00617 decimal_point = locale_data->decimal_point;
00618 decimal_point_len = strlen (decimal_point);
00619
00620 _dbus_assert (decimal_point_len != 0);
00621
00622 decimal_point_pos = NULL;
00623 if (decimal_point[0] != '.' ||
00624 decimal_point[1] != 0)
00625 {
00626 p = nptr;
00627
00628 while (ascii_isspace (*p))
00629 p++;
00630
00631
00632 if (*p == '+' || *p == '-')
00633 p++;
00634
00635 if (p[0] == '0' &&
00636 (p[1] == 'x' || p[1] == 'X'))
00637 {
00638 p += 2;
00639
00640
00641 while (ascii_isxdigit (*p))
00642 p++;
00643
00644 if (*p == '.')
00645 {
00646 decimal_point_pos = p++;
00647
00648 while (ascii_isxdigit (*p))
00649 p++;
00650
00651 if (*p == 'p' || *p == 'P')
00652 p++;
00653 if (*p == '+' || *p == '-')
00654 p++;
00655 while (ascii_isdigit (*p))
00656 p++;
00657 end = p;
00658 }
00659 }
00660 else
00661 {
00662 while (ascii_isdigit (*p))
00663 p++;
00664
00665 if (*p == '.')
00666 {
00667 decimal_point_pos = p++;
00668
00669 while (ascii_isdigit (*p))
00670 p++;
00671
00672 if (*p == 'e' || *p == 'E')
00673 p++;
00674 if (*p == '+' || *p == '-')
00675 p++;
00676 while (ascii_isdigit (*p))
00677 p++;
00678 end = p;
00679 }
00680 }
00681
00682 }
00683
00684
00685
00686 errno = 0;
00687
00688 if (decimal_point_pos)
00689 {
00690 char *copy, *c;
00691
00692
00693 copy = dbus_malloc (end - nptr + 1 + decimal_point_len);
00694
00695 c = copy;
00696 memcpy (c, nptr, decimal_point_pos - nptr);
00697 c += decimal_point_pos - nptr;
00698 memcpy (c, decimal_point, decimal_point_len);
00699 c += decimal_point_len;
00700 memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
00701 c += end - (decimal_point_pos + 1);
00702 *c = 0;
00703
00704 val = strtod (copy, &fail_pos);
00705
00706 if (fail_pos)
00707 {
00708 if (fail_pos > decimal_point_pos)
00709 fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
00710 else
00711 fail_pos = (char *)nptr + (fail_pos - copy);
00712 }
00713
00714 dbus_free (copy);
00715
00716 }
00717 else
00718 val = strtod (nptr, &fail_pos);
00719
00720 if (endptr)
00721 *endptr = fail_pos;
00722
00723 return val;
00724 }
00725 #endif
00726
00727 #ifdef DBUS_BUILD_TESTS
00728
00740 dbus_bool_t
00741 _dbus_string_parse_double (const DBusString *str,
00742 int start,
00743 double *value_return,
00744 int *end_return)
00745 {
00746 double v;
00747 const char *p;
00748 char *end;
00749
00750 p = _dbus_string_get_const_data_len (str, start,
00751 _dbus_string_get_length (str) - start);
00752
00753 end = NULL;
00754 errno = 0;
00755 v = ascii_strtod (p, &end);
00756 if (end == NULL || end == p || errno != 0)
00757 return FALSE;
00758
00759 if (value_return)
00760 *value_return = v;
00761 if (end_return)
00762 *end_return = start + (end - p);
00763
00764 return TRUE;
00765 }
00766 #endif
00767
00769
00775 void
00776 _dbus_generate_pseudorandom_bytes_buffer (char *buffer,
00777 int n_bytes)
00778 {
00779 long tv_usec;
00780 int i;
00781
00782
00783 _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
00784 n_bytes);
00785
00786 _dbus_get_current_time (NULL, &tv_usec);
00787 srand (tv_usec);
00788
00789 i = 0;
00790 while (i < n_bytes)
00791 {
00792 double r;
00793 unsigned int b;
00794
00795 r = rand ();
00796 b = (r / (double) RAND_MAX) * 255.0;
00797
00798 buffer[i] = b;
00799
00800 ++i;
00801 }
00802 }
00803
00810 void
00811 _dbus_generate_random_bytes_buffer (char *buffer,
00812 int n_bytes)
00813 {
00814 DBusString str;
00815
00816 if (!_dbus_string_init (&str))
00817 {
00818 _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
00819 return;
00820 }
00821
00822 if (!_dbus_generate_random_bytes (&str, n_bytes))
00823 {
00824 _dbus_string_free (&str);
00825 _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
00826 return;
00827 }
00828
00829 _dbus_string_copy_to_buffer (&str, buffer, n_bytes);
00830
00831 _dbus_string_free (&str);
00832 }
00833
00842 dbus_bool_t
00843 _dbus_generate_random_ascii (DBusString *str,
00844 int n_bytes)
00845 {
00846 static const char letters[] =
00847 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
00848 int i;
00849 int len;
00850
00851 if (!_dbus_generate_random_bytes (str, n_bytes))
00852 return FALSE;
00853
00854 len = _dbus_string_get_length (str);
00855 i = len - n_bytes;
00856 while (i < len)
00857 {
00858 _dbus_string_set_byte (str, i,
00859 letters[_dbus_string_get_byte (str, i) %
00860 (sizeof (letters) - 1)]);
00861
00862 ++i;
00863 }
00864
00865 _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
00866 n_bytes));
00867
00868 return TRUE;
00869 }
00870
00881 const char*
00882 _dbus_error_from_errno (int error_number)
00883 {
00884 switch (error_number)
00885 {
00886 case 0:
00887 return DBUS_ERROR_FAILED;
00888
00889 #ifdef EPROTONOSUPPORT
00890 case EPROTONOSUPPORT:
00891 return DBUS_ERROR_NOT_SUPPORTED;
00892 #endif
00893 #ifdef EAFNOSUPPORT
00894 case EAFNOSUPPORT:
00895 return DBUS_ERROR_NOT_SUPPORTED;
00896 #endif
00897 #ifdef ENFILE
00898 case ENFILE:
00899 return DBUS_ERROR_LIMITS_EXCEEDED;
00900 #endif
00901 #ifdef EMFILE
00902 case EMFILE:
00903 return DBUS_ERROR_LIMITS_EXCEEDED;
00904 #endif
00905 #ifdef EACCES
00906 case EACCES:
00907 return DBUS_ERROR_ACCESS_DENIED;
00908 #endif
00909 #ifdef EPERM
00910 case EPERM:
00911 return DBUS_ERROR_ACCESS_DENIED;
00912 #endif
00913 #ifdef ENOBUFS
00914 case ENOBUFS:
00915 return DBUS_ERROR_NO_MEMORY;
00916 #endif
00917 #ifdef ENOMEM
00918 case ENOMEM:
00919 return DBUS_ERROR_NO_MEMORY;
00920 #endif
00921 #ifdef EINVAL
00922 case EINVAL:
00923 return DBUS_ERROR_FAILED;
00924 #endif
00925 #ifdef EBADF
00926 case EBADF:
00927 return DBUS_ERROR_FAILED;
00928 #endif
00929 #ifdef EFAULT
00930 case EFAULT:
00931 return DBUS_ERROR_FAILED;
00932 #endif
00933 #ifdef ENOTSOCK
00934 case ENOTSOCK:
00935 return DBUS_ERROR_FAILED;
00936 #endif
00937 #ifdef EISCONN
00938 case EISCONN:
00939 return DBUS_ERROR_FAILED;
00940 #endif
00941 #ifdef ECONNREFUSED
00942 case ECONNREFUSED:
00943 return DBUS_ERROR_NO_SERVER;
00944 #endif
00945 #ifdef ETIMEDOUT
00946 case ETIMEDOUT:
00947 return DBUS_ERROR_TIMEOUT;
00948 #endif
00949 #ifdef ENETUNREACH
00950 case ENETUNREACH:
00951 return DBUS_ERROR_NO_NETWORK;
00952 #endif
00953 #ifdef EADDRINUSE
00954 case EADDRINUSE:
00955 return DBUS_ERROR_ADDRESS_IN_USE;
00956 #endif
00957 #ifdef EEXIST
00958 case EEXIST:
00959 return DBUS_ERROR_FILE_EXISTS;
00960 #endif
00961 #ifdef ENOENT
00962 case ENOENT:
00963 return DBUS_ERROR_FILE_NOT_FOUND;
00964 #endif
00965 }
00966
00967 return DBUS_ERROR_FAILED;
00968 }
00969
00973 void
00974 _dbus_set_errno_to_zero (void)
00975 {
00976 errno = 0;
00977 }
00978
00983 dbus_bool_t
00984 _dbus_get_is_errno_nonzero (void)
00985 {
00986 return errno != 0;
00987 }
00988
00993 dbus_bool_t
00994 _dbus_get_is_errno_enomem (void)
00995 {
00996 return errno == ENOMEM;
00997 }
00998
01003 dbus_bool_t
01004 _dbus_get_is_errno_eintr (void)
01005 {
01006 return errno == EINTR;
01007 }
01008
01013 const char*
01014 _dbus_strerror_from_errno (void)
01015 {
01016 return _dbus_strerror (errno);
01017 }
01018
01021