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 return (clearenv () == 0);
00189 }
00190
00191
00192
00193
00194
00195
00196
00197 void
00198 _dbus_pipe_init (DBusPipe *pipe,
00199 int fd)
00200 {
00201 pipe->fd_or_handle = fd;
00202 }
00203
00209 void
00210 _dbus_pipe_init_stdout (DBusPipe *pipe)
00211 {
00212 _dbus_pipe_init (pipe, 1);
00213 }
00214
00222 dbus_bool_t
00223 _dbus_pipe_is_valid(DBusPipe *pipe)
00224 {
00225 return pipe->fd_or_handle >= 0;
00226 }
00227
00234 dbus_bool_t
00235 _dbus_pipe_is_stdout_or_stderr (DBusPipe *pipe)
00236 {
00237 return pipe->fd_or_handle == 1 || pipe->fd_or_handle == 2;
00238 }
00239
00244 void
00245 _dbus_pipe_invalidate (DBusPipe *pipe)
00246 {
00247 pipe->fd_or_handle = -1;
00248 }
00249
00258 dbus_bool_t
00259 _dbus_split_paths_and_append (DBusString *dirs,
00260 const char *suffix,
00261 DBusList **dir_list)
00262 {
00263 int start;
00264 int i;
00265 int len;
00266 char *cpath;
00267 DBusString file_suffix;
00268
00269 start = 0;
00270 i = 0;
00271
00272 _dbus_string_init_const (&file_suffix, suffix);
00273
00274 len = _dbus_string_get_length (dirs);
00275
00276 while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i))
00277 {
00278 DBusString path;
00279
00280 if (!_dbus_string_init (&path))
00281 goto oom;
00282
00283 if (!_dbus_string_copy_len (dirs,
00284 start,
00285 i - start,
00286 &path,
00287 0))
00288 {
00289 _dbus_string_free (&path);
00290 goto oom;
00291 }
00292
00293 _dbus_string_chop_white (&path);
00294
00295
00296 if (_dbus_string_get_length (&path) == 0)
00297 goto next;
00298
00299 if (!_dbus_concat_dir_and_file (&path,
00300 &file_suffix))
00301 {
00302 _dbus_string_free (&path);
00303 goto oom;
00304 }
00305
00306 if (!_dbus_string_copy_data(&path, &cpath))
00307 {
00308 _dbus_string_free (&path);
00309 goto oom;
00310 }
00311
00312 if (!_dbus_list_append (dir_list, cpath))
00313 {
00314 _dbus_string_free (&path);
00315 dbus_free (cpath);
00316 goto oom;
00317 }
00318
00319 next:
00320 _dbus_string_free (&path);
00321 start = i + 1;
00322 }
00323
00324 if (start != len)
00325 {
00326 DBusString path;
00327
00328 if (!_dbus_string_init (&path))
00329 goto oom;
00330
00331 if (!_dbus_string_copy_len (dirs,
00332 start,
00333 len - start,
00334 &path,
00335 0))
00336 {
00337 _dbus_string_free (&path);
00338 goto oom;
00339 }
00340
00341 if (!_dbus_concat_dir_and_file (&path,
00342 &file_suffix))
00343 {
00344 _dbus_string_free (&path);
00345 goto oom;
00346 }
00347
00348 if (!_dbus_string_copy_data(&path, &cpath))
00349 {
00350 _dbus_string_free (&path);
00351 goto oom;
00352 }
00353
00354 if (!_dbus_list_append (dir_list, cpath))
00355 {
00356 _dbus_string_free (&path);
00357 dbus_free (cpath);
00358 goto oom;
00359 }
00360
00361 _dbus_string_free (&path);
00362 }
00363
00364 return TRUE;
00365
00366 oom:
00367 _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL);
00368 _dbus_list_clear (dir_list);
00369 return FALSE;
00370 }
00371
00386 dbus_bool_t
00387 _dbus_string_append_int (DBusString *str,
00388 long value)
00389 {
00390
00391 #define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1)
00392 int orig_len;
00393 int i;
00394 char *buf;
00395
00396 orig_len = _dbus_string_get_length (str);
00397
00398 if (!_dbus_string_lengthen (str, MAX_LONG_LEN))
00399 return FALSE;
00400
00401 buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN);
00402
00403 snprintf (buf, MAX_LONG_LEN, "%ld", value);
00404
00405 i = 0;
00406 while (*buf)
00407 {
00408 ++buf;
00409 ++i;
00410 }
00411
00412 _dbus_string_shorten (str, MAX_LONG_LEN - i);
00413
00414 return TRUE;
00415 }
00416
00424 dbus_bool_t
00425 _dbus_string_append_uint (DBusString *str,
00426 unsigned long value)
00427 {
00428
00429 #define MAX_ULONG_LEN (MAX_LONG_LEN * 2)
00430 int orig_len;
00431 int i;
00432 char *buf;
00433
00434 orig_len = _dbus_string_get_length (str);
00435
00436 if (!_dbus_string_lengthen (str, MAX_ULONG_LEN))
00437 return FALSE;
00438
00439 buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN);
00440
00441 snprintf (buf, MAX_ULONG_LEN, "%lu", value);
00442
00443 i = 0;
00444 while (*buf)
00445 {
00446 ++buf;
00447 ++i;
00448 }
00449
00450 _dbus_string_shorten (str, MAX_ULONG_LEN - i);
00451
00452 return TRUE;
00453 }
00454
00455 #ifdef DBUS_BUILD_TESTS
00456
00463 dbus_bool_t
00464 _dbus_string_append_double (DBusString *str,
00465 double value)
00466 {
00467 #define MAX_DOUBLE_LEN 64
00468 int orig_len;
00469 char *buf;
00470 int i;
00471
00472 orig_len = _dbus_string_get_length (str);
00473
00474 if (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN))
00475 return FALSE;
00476
00477 buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN);
00478
00479 snprintf (buf, MAX_LONG_LEN, "%g", value);
00480
00481 i = 0;
00482 while (*buf)
00483 {
00484 ++buf;
00485 ++i;
00486 }
00487
00488 _dbus_string_shorten (str, MAX_DOUBLE_LEN - i);
00489
00490 return TRUE;
00491 }
00492 #endif
00493
00506 dbus_bool_t
00507 _dbus_string_parse_int (const DBusString *str,
00508 int start,
00509 long *value_return,
00510 int *end_return)
00511 {
00512 long v;
00513 const char *p;
00514 char *end;
00515
00516 p = _dbus_string_get_const_data_len (str, start,
00517 _dbus_string_get_length (str) - start);
00518
00519 end = NULL;
00520 errno = 0;
00521 v = strtol (p, &end, 0);
00522 if (end == NULL || end == p || errno != 0)
00523 return FALSE;
00524
00525 if (value_return)
00526 *value_return = v;
00527 if (end_return)
00528 *end_return = start + (end - p);
00529
00530 return TRUE;
00531 }
00532
00545 dbus_bool_t
00546 _dbus_string_parse_uint (const DBusString *str,
00547 int start,
00548 unsigned long *value_return,
00549 int *end_return)
00550 {
00551 unsigned long v;
00552 const char *p;
00553 char *end;
00554
00555 p = _dbus_string_get_const_data_len (str, start,
00556 _dbus_string_get_length (str) - start);
00557
00558 end = NULL;
00559 errno = 0;
00560 v = strtoul (p, &end, 0);
00561 if (end == NULL || end == p || errno != 0)
00562 return FALSE;
00563
00564 if (value_return)
00565 *value_return = v;
00566 if (end_return)
00567 *end_return = start + (end - p);
00568
00569 return TRUE;
00570 }
00571
00572 #ifdef DBUS_BUILD_TESTS
00573 static dbus_bool_t
00574 ascii_isspace (char c)
00575 {
00576 return (c == ' ' ||
00577 c == '\f' ||
00578 c == '\n' ||
00579 c == '\r' ||
00580 c == '\t' ||
00581 c == '\v');
00582 }
00583 #endif
00584
00585 #ifdef DBUS_BUILD_TESTS
00586 static dbus_bool_t
00587 ascii_isdigit (char c)
00588 {
00589 return c >= '0' && c <= '9';
00590 }
00591 #endif
00592
00593 #ifdef DBUS_BUILD_TESTS
00594 static dbus_bool_t
00595 ascii_isxdigit (char c)
00596 {
00597 return (ascii_isdigit (c) ||
00598 (c >= 'a' && c <= 'f') ||
00599 (c >= 'A' && c <= 'F'));
00600 }
00601 #endif
00602
00603 #ifdef DBUS_BUILD_TESTS
00604
00605
00606
00607
00608
00609 static double
00610 ascii_strtod (const char *nptr,
00611 char **endptr)
00612 {
00613
00614
00615
00616
00617 char *fail_pos;
00618 double val;
00619 struct lconv *locale_data;
00620 const char *decimal_point;
00621 int decimal_point_len;
00622 const char *p, *decimal_point_pos;
00623 const char *end = NULL;
00624
00625 fail_pos = NULL;
00626
00627 locale_data = localeconv ();
00628 decimal_point = locale_data->decimal_point;
00629 decimal_point_len = strlen (decimal_point);
00630
00631 _dbus_assert (decimal_point_len != 0);
00632
00633 decimal_point_pos = NULL;
00634 if (decimal_point[0] != '.' ||
00635 decimal_point[1] != 0)
00636 {
00637 p = nptr;
00638
00639 while (ascii_isspace (*p))
00640 p++;
00641
00642
00643 if (*p == '+' || *p == '-')
00644 p++;
00645
00646 if (p[0] == '0' &&
00647 (p[1] == 'x' || p[1] == 'X'))
00648 {
00649 p += 2;
00650
00651
00652 while (ascii_isxdigit (*p))
00653 p++;
00654
00655 if (*p == '.')
00656 {
00657 decimal_point_pos = p++;
00658
00659 while (ascii_isxdigit (*p))
00660 p++;
00661
00662 if (*p == 'p' || *p == 'P')
00663 p++;
00664 if (*p == '+' || *p == '-')
00665 p++;
00666 while (ascii_isdigit (*p))
00667 p++;
00668 end = p;
00669 }
00670 }
00671 else
00672 {
00673 while (ascii_isdigit (*p))
00674 p++;
00675
00676 if (*p == '.')
00677 {
00678 decimal_point_pos = p++;
00679
00680 while (ascii_isdigit (*p))
00681 p++;
00682
00683 if (*p == 'e' || *p == 'E')
00684 p++;
00685 if (*p == '+' || *p == '-')
00686 p++;
00687 while (ascii_isdigit (*p))
00688 p++;
00689 end = p;
00690 }
00691 }
00692
00693 }
00694
00695
00696
00697 errno = 0;
00698
00699 if (decimal_point_pos)
00700 {
00701 char *copy, *c;
00702
00703
00704 copy = dbus_malloc (end - nptr + 1 + decimal_point_len);
00705
00706 c = copy;
00707 memcpy (c, nptr, decimal_point_pos - nptr);
00708 c += decimal_point_pos - nptr;
00709 memcpy (c, decimal_point, decimal_point_len);
00710 c += decimal_point_len;
00711 memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
00712 c += end - (decimal_point_pos + 1);
00713 *c = 0;
00714
00715 val = strtod (copy, &fail_pos);
00716
00717 if (fail_pos)
00718 {
00719 if (fail_pos > decimal_point_pos)
00720 fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
00721 else
00722 fail_pos = (char *)nptr + (fail_pos - copy);
00723 }
00724
00725 dbus_free (copy);
00726
00727 }
00728 else
00729 val = strtod (nptr, &fail_pos);
00730
00731 if (endptr)
00732 *endptr = fail_pos;
00733
00734 return val;
00735 }
00736 #endif
00737
00738 #ifdef DBUS_BUILD_TESTS
00739
00751 dbus_bool_t
00752 _dbus_string_parse_double (const DBusString *str,
00753 int start,
00754 double *value_return,
00755 int *end_return)
00756 {
00757 double v;
00758 const char *p;
00759 char *end;
00760
00761 p = _dbus_string_get_const_data_len (str, start,
00762 _dbus_string_get_length (str) - start);
00763
00764
00765
00766
00767 if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
00768 return FALSE;
00769
00770 end = NULL;
00771 errno = 0;
00772 v = ascii_strtod (p, &end);
00773 if (end == NULL || end == p || errno != 0)
00774 return FALSE;
00775
00776 if (value_return)
00777 *value_return = v;
00778 if (end_return)
00779 *end_return = start + (end - p);
00780
00781 return TRUE;
00782 }
00783 #endif
00784
00786
00792 void
00793 _dbus_generate_pseudorandom_bytes_buffer (char *buffer,
00794 int n_bytes)
00795 {
00796 long tv_usec;
00797 int i;
00798
00799
00800 _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
00801 n_bytes);
00802
00803 _dbus_get_current_time (NULL, &tv_usec);
00804 srand (tv_usec);
00805
00806 i = 0;
00807 while (i < n_bytes)
00808 {
00809 double r;
00810 unsigned int b;
00811
00812 r = rand ();
00813 b = (r / (double) RAND_MAX) * 255.0;
00814
00815 buffer[i] = b;
00816
00817 ++i;
00818 }
00819 }
00820
00827 void
00828 _dbus_generate_random_bytes_buffer (char *buffer,
00829 int n_bytes)
00830 {
00831 DBusString str;
00832
00833 if (!_dbus_string_init (&str))
00834 {
00835 _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
00836 return;
00837 }
00838
00839 if (!_dbus_generate_random_bytes (&str, n_bytes))
00840 {
00841 _dbus_string_free (&str);
00842 _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
00843 return;
00844 }
00845
00846 _dbus_string_copy_to_buffer (&str, buffer, n_bytes);
00847
00848 _dbus_string_free (&str);
00849 }
00850
00859 dbus_bool_t
00860 _dbus_generate_random_ascii (DBusString *str,
00861 int n_bytes)
00862 {
00863 static const char letters[] =
00864 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
00865 int i;
00866 int len;
00867
00868 if (!_dbus_generate_random_bytes (str, n_bytes))
00869 return FALSE;
00870
00871 len = _dbus_string_get_length (str);
00872 i = len - n_bytes;
00873 while (i < len)
00874 {
00875 _dbus_string_set_byte (str, i,
00876 letters[_dbus_string_get_byte (str, i) %
00877 (sizeof (letters) - 1)]);
00878
00879 ++i;
00880 }
00881
00882 _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
00883 n_bytes));
00884
00885 return TRUE;
00886 }
00887
00898 const char*
00899 _dbus_error_from_errno (int error_number)
00900 {
00901 switch (error_number)
00902 {
00903 case 0:
00904 return DBUS_ERROR_FAILED;
00905
00906 #ifdef EPROTONOSUPPORT
00907 case EPROTONOSUPPORT:
00908 return DBUS_ERROR_NOT_SUPPORTED;
00909 #endif
00910 #ifdef EAFNOSUPPORT
00911 case EAFNOSUPPORT:
00912 return DBUS_ERROR_NOT_SUPPORTED;
00913 #endif
00914 #ifdef ENFILE
00915 case ENFILE:
00916 return DBUS_ERROR_LIMITS_EXCEEDED;
00917 #endif
00918 #ifdef EMFILE
00919 case EMFILE:
00920 return DBUS_ERROR_LIMITS_EXCEEDED;
00921 #endif
00922 #ifdef EACCES
00923 case EACCES:
00924 return DBUS_ERROR_ACCESS_DENIED;
00925 #endif
00926 #ifdef EPERM
00927 case EPERM:
00928 return DBUS_ERROR_ACCESS_DENIED;
00929 #endif
00930 #ifdef ENOBUFS
00931 case ENOBUFS:
00932 return DBUS_ERROR_NO_MEMORY;
00933 #endif
00934 #ifdef ENOMEM
00935 case ENOMEM:
00936 return DBUS_ERROR_NO_MEMORY;
00937 #endif
00938 #ifdef EINVAL
00939 case EINVAL:
00940 return DBUS_ERROR_FAILED;
00941 #endif
00942 #ifdef EBADF
00943 case EBADF:
00944 return DBUS_ERROR_FAILED;
00945 #endif
00946 #ifdef EFAULT
00947 case EFAULT:
00948 return DBUS_ERROR_FAILED;
00949 #endif
00950 #ifdef ENOTSOCK
00951 case ENOTSOCK:
00952 return DBUS_ERROR_FAILED;
00953 #endif
00954 #ifdef EISCONN
00955 case EISCONN:
00956 return DBUS_ERROR_FAILED;
00957 #endif
00958 #ifdef ECONNREFUSED
00959 case ECONNREFUSED:
00960 return DBUS_ERROR_NO_SERVER;
00961 #endif
00962 #ifdef ETIMEDOUT
00963 case ETIMEDOUT:
00964 return DBUS_ERROR_TIMEOUT;
00965 #endif
00966 #ifdef ENETUNREACH
00967 case ENETUNREACH:
00968 return DBUS_ERROR_NO_NETWORK;
00969 #endif
00970 #ifdef EADDRINUSE
00971 case EADDRINUSE:
00972 return DBUS_ERROR_ADDRESS_IN_USE;
00973 #endif
00974 #ifdef EEXIST
00975 case EEXIST:
00976 return DBUS_ERROR_FILE_EXISTS;
00977 #endif
00978 #ifdef ENOENT
00979 case ENOENT:
00980 return DBUS_ERROR_FILE_NOT_FOUND;
00981 #endif
00982 }
00983
00984 return DBUS_ERROR_FAILED;
00985 }
00986
00990 void
00991 _dbus_set_errno_to_zero (void)
00992 {
00993 errno = 0;
00994 }
00995
01000 dbus_bool_t
01001 _dbus_get_is_errno_nonzero (void)
01002 {
01003 return errno != 0;
01004 }
01005
01010 dbus_bool_t
01011 _dbus_get_is_errno_enomem (void)
01012 {
01013 return errno == ENOMEM;
01014 }
01015
01020 dbus_bool_t
01021 _dbus_get_is_errno_eintr (void)
01022 {
01023 return errno == EINTR;
01024 }
01025
01030 const char*
01031 _dbus_strerror_from_errno (void)
01032 {
01033 return _dbus_strerror (errno);
01034 }
01035
01038