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-sysdeps-unix.h"
00028 #include "dbus-threads.h"
00029 #include "dbus-protocol.h"
00030 #include "dbus-transport.h"
00031 #include "dbus-string.h"
00032 #include "dbus-userdb.h"
00033 #include "dbus-list.h"
00034 #include "dbus-credentials.h"
00035
00036 #include <sys/types.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <signal.h>
00040 #include <unistd.h>
00041 #include <stdio.h>
00042 #include <fcntl.h>
00043 #include <sys/socket.h>
00044 #include <dirent.h>
00045 #include <sys/un.h>
00046 #include <pwd.h>
00047 #include <time.h>
00048 #include <locale.h>
00049 #include <sys/time.h>
00050 #include <sys/stat.h>
00051 #include <sys/wait.h>
00052 #include <netinet/in.h>
00053 #include <netdb.h>
00054 #include <grp.h>
00055
00056 #ifdef HAVE_ERRNO_H
00057 #include <errno.h>
00058 #endif
00059 #ifdef HAVE_WRITEV
00060 #include <sys/uio.h>
00061 #endif
00062 #ifdef HAVE_POLL
00063 #include <sys/poll.h>
00064 #endif
00065 #ifdef HAVE_BACKTRACE
00066 #include <execinfo.h>
00067 #endif
00068 #ifdef HAVE_GETPEERUCRED
00069 #include <ucred.h>
00070 #endif
00071
00072 #ifndef O_BINARY
00073 #define O_BINARY 0
00074 #endif
00075
00076 #ifndef HAVE_SOCKLEN_T
00077 #define socklen_t int
00078 #endif
00079
00080 static dbus_bool_t
00081 _dbus_open_socket (int *fd_p,
00082 int domain,
00083 int type,
00084 int protocol,
00085 DBusError *error)
00086 {
00087 *fd_p = socket (domain, type, protocol);
00088 if (*fd_p >= 0)
00089 {
00090 _dbus_verbose ("socket fd %d opened\n", *fd_p);
00091 return TRUE;
00092 }
00093 else
00094 {
00095 dbus_set_error(error,
00096 _dbus_error_from_errno (errno),
00097 "Failed to open socket: %s",
00098 _dbus_strerror (errno));
00099 return FALSE;
00100 }
00101 }
00102
00103 dbus_bool_t
00104 _dbus_open_tcp_socket (int *fd,
00105 DBusError *error)
00106 {
00107 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
00108 }
00109
00117 dbus_bool_t
00118 _dbus_open_unix_socket (int *fd,
00119 DBusError *error)
00120 {
00121 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00122 }
00123
00132 dbus_bool_t
00133 _dbus_close_socket (int fd,
00134 DBusError *error)
00135 {
00136 return _dbus_close (fd, error);
00137 }
00138
00148 int
00149 _dbus_read_socket (int fd,
00150 DBusString *buffer,
00151 int count)
00152 {
00153 return _dbus_read (fd, buffer, count);
00154 }
00155
00166 int
00167 _dbus_write_socket (int fd,
00168 const DBusString *buffer,
00169 int start,
00170 int len)
00171 {
00172 return _dbus_write (fd, buffer, start, len);
00173 }
00174
00185 int
00186 _dbus_pipe_write (DBusPipe *pipe,
00187 const DBusString *buffer,
00188 int start,
00189 int len,
00190 DBusError *error)
00191 {
00192 int written;
00193
00194 written = _dbus_write (pipe->fd_or_handle, buffer, start, len);
00195 if (written < 0)
00196 {
00197 dbus_set_error (error, DBUS_ERROR_FAILED,
00198 "Writing to pipe: %s\n",
00199 _dbus_strerror (errno));
00200 }
00201 return written;
00202 }
00203
00211 int
00212 _dbus_pipe_close (DBusPipe *pipe,
00213 DBusError *error)
00214 {
00215 if (_dbus_close (pipe->fd_or_handle, error) < 0)
00216 {
00217 return -1;
00218 }
00219 else
00220 {
00221 _dbus_pipe_invalidate (pipe);
00222 return 0;
00223 }
00224 }
00225
00239 int
00240 _dbus_write_socket_two (int fd,
00241 const DBusString *buffer1,
00242 int start1,
00243 int len1,
00244 const DBusString *buffer2,
00245 int start2,
00246 int len2)
00247 {
00248 return _dbus_write_two (fd, buffer1, start1, len1,
00249 buffer2, start2, len2);
00250 }
00251
00252
00269 int
00270 _dbus_read (int fd,
00271 DBusString *buffer,
00272 int count)
00273 {
00274 int bytes_read;
00275 int start;
00276 char *data;
00277
00278 _dbus_assert (count >= 0);
00279
00280 start = _dbus_string_get_length (buffer);
00281
00282 if (!_dbus_string_lengthen (buffer, count))
00283 {
00284 errno = ENOMEM;
00285 return -1;
00286 }
00287
00288 data = _dbus_string_get_data_len (buffer, start, count);
00289
00290 again:
00291
00292 bytes_read = read (fd, data, count);
00293
00294 if (bytes_read < 0)
00295 {
00296 if (errno == EINTR)
00297 goto again;
00298 else
00299 {
00300
00301 _dbus_string_set_length (buffer, start);
00302 return -1;
00303 }
00304 }
00305 else
00306 {
00307
00308 _dbus_string_set_length (buffer, start + bytes_read);
00309
00310 #if 0
00311 if (bytes_read > 0)
00312 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00313 #endif
00314
00315 return bytes_read;
00316 }
00317 }
00318
00329 int
00330 _dbus_write (int fd,
00331 const DBusString *buffer,
00332 int start,
00333 int len)
00334 {
00335 const char *data;
00336 int bytes_written;
00337
00338 data = _dbus_string_get_const_data_len (buffer, start, len);
00339
00340 again:
00341
00342 bytes_written = write (fd, data, len);
00343
00344 if (bytes_written < 0 && errno == EINTR)
00345 goto again;
00346
00347 #if 0
00348 if (bytes_written > 0)
00349 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00350 #endif
00351
00352 return bytes_written;
00353 }
00354
00375 int
00376 _dbus_write_two (int fd,
00377 const DBusString *buffer1,
00378 int start1,
00379 int len1,
00380 const DBusString *buffer2,
00381 int start2,
00382 int len2)
00383 {
00384 _dbus_assert (buffer1 != NULL);
00385 _dbus_assert (start1 >= 0);
00386 _dbus_assert (start2 >= 0);
00387 _dbus_assert (len1 >= 0);
00388 _dbus_assert (len2 >= 0);
00389
00390 #ifdef HAVE_WRITEV
00391 {
00392 struct iovec vectors[2];
00393 const char *data1;
00394 const char *data2;
00395 int bytes_written;
00396
00397 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00398
00399 if (buffer2 != NULL)
00400 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00401 else
00402 {
00403 data2 = NULL;
00404 start2 = 0;
00405 len2 = 0;
00406 }
00407
00408 vectors[0].iov_base = (char*) data1;
00409 vectors[0].iov_len = len1;
00410 vectors[1].iov_base = (char*) data2;
00411 vectors[1].iov_len = len2;
00412
00413 again:
00414
00415 bytes_written = writev (fd,
00416 vectors,
00417 data2 ? 2 : 1);
00418
00419 if (bytes_written < 0 && errno == EINTR)
00420 goto again;
00421
00422 return bytes_written;
00423 }
00424 #else
00425 {
00426 int ret1;
00427
00428 ret1 = _dbus_write (fd, buffer1, start1, len1);
00429 if (ret1 == len1 && buffer2 != NULL)
00430 {
00431 ret2 = _dbus_write (fd, buffer2, start2, len2);
00432 if (ret2 < 0)
00433 ret2 = 0;
00434
00435 return ret1 + ret2;
00436 }
00437 else
00438 return ret1;
00439 }
00440 #endif
00441 }
00442
00443 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00444
00472 int
00473 _dbus_connect_unix_socket (const char *path,
00474 dbus_bool_t abstract,
00475 DBusError *error)
00476 {
00477 int fd;
00478 size_t path_len;
00479 struct sockaddr_un addr;
00480
00481 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00482
00483 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00484 path, abstract);
00485
00486
00487 if (!_dbus_open_unix_socket (&fd, error))
00488 {
00489 _DBUS_ASSERT_ERROR_IS_SET(error);
00490 return -1;
00491 }
00492 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00493
00494 _DBUS_ZERO (addr);
00495 addr.sun_family = AF_UNIX;
00496 path_len = strlen (path);
00497
00498 if (abstract)
00499 {
00500 #ifdef HAVE_ABSTRACT_SOCKETS
00501 addr.sun_path[0] = '\0';
00502 path_len++;
00503
00504 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00505 {
00506 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00507 "Abstract socket name too long\n");
00508 _dbus_close (fd, NULL);
00509 return -1;
00510 }
00511
00512 strncpy (&addr.sun_path[1], path, path_len);
00513
00514 #else
00515 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00516 "Operating system does not support abstract socket namespace\n");
00517 _dbus_close (fd, NULL);
00518 return -1;
00519 #endif
00520 }
00521 else
00522 {
00523 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00524 {
00525 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00526 "Socket name too long\n");
00527 _dbus_close (fd, NULL);
00528 return -1;
00529 }
00530
00531 strncpy (addr.sun_path, path, path_len);
00532 }
00533
00534 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00535 {
00536 dbus_set_error (error,
00537 _dbus_error_from_errno (errno),
00538 "Failed to connect to socket %s: %s",
00539 path, _dbus_strerror (errno));
00540
00541 _dbus_close (fd, NULL);
00542 fd = -1;
00543
00544 return -1;
00545 }
00546
00547 if (!_dbus_set_fd_nonblocking (fd, error))
00548 {
00549 _DBUS_ASSERT_ERROR_IS_SET (error);
00550
00551 _dbus_close (fd, NULL);
00552 fd = -1;
00553
00554 return -1;
00555 }
00556
00557 return fd;
00558 }
00559
00569 static dbus_bool_t
00570 _dbus_set_local_creds (int fd, dbus_bool_t on)
00571 {
00572 dbus_bool_t retval = TRUE;
00573
00574 #if defined(HAVE_CMSGCRED)
00575
00576
00577
00578 #elif defined(LOCAL_CREDS)
00579 int val = on ? 1 : 0;
00580 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00581 {
00582 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00583 retval = FALSE;
00584 }
00585 else
00586 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00587 on ? "enabled" : "disabled", fd);
00588 #endif
00589
00590 return retval;
00591 }
00592
00608 int
00609 _dbus_listen_unix_socket (const char *path,
00610 dbus_bool_t abstract,
00611 DBusError *error)
00612 {
00613 int listen_fd;
00614 struct sockaddr_un addr;
00615 size_t path_len;
00616
00617 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00618
00619 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00620 path, abstract);
00621
00622 if (!_dbus_open_unix_socket (&listen_fd, error))
00623 {
00624 _DBUS_ASSERT_ERROR_IS_SET(error);
00625 return -1;
00626 }
00627 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00628
00629 _DBUS_ZERO (addr);
00630 addr.sun_family = AF_UNIX;
00631 path_len = strlen (path);
00632
00633 if (abstract)
00634 {
00635 #ifdef HAVE_ABSTRACT_SOCKETS
00636
00637
00638
00639 addr.sun_path[0] = '\0';
00640 path_len++;
00641
00642 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00643 {
00644 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00645 "Abstract socket name too long\n");
00646 _dbus_close (listen_fd, NULL);
00647 return -1;
00648 }
00649
00650 strncpy (&addr.sun_path[1], path, path_len);
00651
00652 #else
00653 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00654 "Operating system does not support abstract socket namespace\n");
00655 _dbus_close (listen_fd, NULL);
00656 return -1;
00657 #endif
00658 }
00659 else
00660 {
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 {
00672 struct stat sb;
00673
00674 if (stat (path, &sb) == 0 &&
00675 S_ISSOCK (sb.st_mode))
00676 unlink (path);
00677 }
00678
00679 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00680 {
00681 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00682 "Abstract socket name too long\n");
00683 _dbus_close (listen_fd, NULL);
00684 return -1;
00685 }
00686
00687 strncpy (addr.sun_path, path, path_len);
00688 }
00689
00690 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00691 {
00692 dbus_set_error (error, _dbus_error_from_errno (errno),
00693 "Failed to bind socket \"%s\": %s",
00694 path, _dbus_strerror (errno));
00695 _dbus_close (listen_fd, NULL);
00696 return -1;
00697 }
00698
00699 if (listen (listen_fd, 30 ) < 0)
00700 {
00701 dbus_set_error (error, _dbus_error_from_errno (errno),
00702 "Failed to listen on socket \"%s\": %s",
00703 path, _dbus_strerror (errno));
00704 _dbus_close (listen_fd, NULL);
00705 return -1;
00706 }
00707
00708 if (!_dbus_set_local_creds (listen_fd, TRUE))
00709 {
00710 dbus_set_error (error, _dbus_error_from_errno (errno),
00711 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
00712 path, _dbus_strerror (errno));
00713 close (listen_fd);
00714 return -1;
00715 }
00716
00717 if (!_dbus_set_fd_nonblocking (listen_fd, error))
00718 {
00719 _DBUS_ASSERT_ERROR_IS_SET (error);
00720 _dbus_close (listen_fd, NULL);
00721 return -1;
00722 }
00723
00724
00725
00726
00727 if (!abstract && chmod (path, 0777) < 0)
00728 _dbus_warn ("Could not set mode 0777 on socket %s\n",
00729 path);
00730
00731 return listen_fd;
00732 }
00733
00744 int
00745 _dbus_connect_tcp_socket (const char *host,
00746 dbus_uint32_t port,
00747 DBusError *error)
00748 {
00749 int fd;
00750 struct sockaddr_in addr;
00751 struct hostent *he;
00752 struct in_addr *haddr;
00753
00754 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00755
00756
00757 if (!_dbus_open_tcp_socket (&fd, error))
00758 {
00759 _DBUS_ASSERT_ERROR_IS_SET(error);
00760
00761 return -1;
00762 }
00763 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00764
00765 if (host == NULL)
00766 host = "localhost";
00767
00768 he = gethostbyname (host);
00769 if (he == NULL)
00770 {
00771 dbus_set_error (error,
00772 _dbus_error_from_errno (errno),
00773 "Failed to lookup hostname: %s",
00774 host);
00775 _dbus_close (fd, NULL);
00776 return -1;
00777 }
00778
00779 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
00780
00781 _DBUS_ZERO (addr);
00782 memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
00783 addr.sin_family = AF_INET;
00784 addr.sin_port = htons (port);
00785
00786 if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
00787 {
00788 dbus_set_error (error,
00789 _dbus_error_from_errno (errno),
00790 "Failed to connect to socket %s:%d %s",
00791 host, port, _dbus_strerror (errno));
00792
00793 _dbus_close (fd, NULL);
00794 fd = -1;
00795
00796 return -1;
00797 }
00798
00799 if (!_dbus_set_fd_nonblocking (fd, error))
00800 {
00801 _dbus_close (fd, NULL);
00802 fd = -1;
00803
00804 return -1;
00805 }
00806
00807 return fd;
00808 }
00809
00822 int
00823 _dbus_listen_tcp_socket (const char *host,
00824 dbus_uint32_t *port,
00825 dbus_bool_t inaddr_any,
00826 DBusError *error)
00827 {
00828 int listen_fd;
00829 struct sockaddr_in addr;
00830 socklen_t len = (socklen_t) sizeof (struct sockaddr);
00831
00832 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00833
00834 if (!_dbus_open_tcp_socket (&listen_fd, error))
00835 {
00836 _DBUS_ASSERT_ERROR_IS_SET(error);
00837 return -1;
00838 }
00839 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00840
00841 _DBUS_ZERO (addr);
00842
00843 if (inaddr_any)
00844 {
00845 addr.sin_addr.s_addr = INADDR_ANY;
00846 }
00847 else
00848 {
00849 struct hostent *he;
00850 struct in_addr *haddr;
00851
00852 he = gethostbyname (host);
00853 if (he == NULL)
00854 {
00855 dbus_set_error (error,
00856 _dbus_error_from_errno (errno),
00857 "Failed to lookup hostname: %s",
00858 host);
00859 _dbus_close (listen_fd, NULL);
00860 return -1;
00861 }
00862
00863 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
00864
00865 memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
00866 }
00867
00868 addr.sin_family = AF_INET;
00869 addr.sin_port = htons (*port);
00870
00871 if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
00872 {
00873 dbus_set_error (error, _dbus_error_from_errno (errno),
00874 "Failed to bind socket \"%s:%d\": %s",
00875 host, *port, _dbus_strerror (errno));
00876 _dbus_close (listen_fd, NULL);
00877 return -1;
00878 }
00879
00880 if (listen (listen_fd, 30 ) < 0)
00881 {
00882 dbus_set_error (error, _dbus_error_from_errno (errno),
00883 "Failed to listen on socket \"%s:%d\": %s",
00884 host, *port, _dbus_strerror (errno));
00885 _dbus_close (listen_fd, NULL);
00886 return -1;
00887 }
00888
00889 getsockname(listen_fd, (struct sockaddr*) &addr, &len);
00890 *port = (dbus_uint32_t) ntohs(addr.sin_port);
00891
00892 if (!_dbus_set_fd_nonblocking (listen_fd, error))
00893 {
00894 _dbus_close (listen_fd, NULL);
00895 return -1;
00896 }
00897
00898 return listen_fd;
00899 }
00900
00901 static dbus_bool_t
00902 write_credentials_byte (int server_fd,
00903 DBusError *error)
00904 {
00905 int bytes_written;
00906 char buf[1] = { '\0' };
00907 #if defined(HAVE_CMSGCRED)
00908 struct {
00909 struct cmsghdr hdr;
00910 struct cmsgcred cred;
00911 } cmsg;
00912 struct iovec iov;
00913 struct msghdr msg;
00914 iov.iov_base = buf;
00915 iov.iov_len = 1;
00916
00917 memset (&msg, 0, sizeof (msg));
00918 msg.msg_iov = &iov;
00919 msg.msg_iovlen = 1;
00920
00921 msg.msg_control = &cmsg;
00922 msg.msg_controllen = sizeof (cmsg);
00923 memset (&cmsg, 0, sizeof (cmsg));
00924 cmsg.hdr.cmsg_len = sizeof (cmsg);
00925 cmsg.hdr.cmsg_level = SOL_SOCKET;
00926 cmsg.hdr.cmsg_type = SCM_CREDS;
00927 #endif
00928
00929 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00930
00931 again:
00932
00933 #if defined(HAVE_CMSGCRED)
00934 bytes_written = sendmsg (server_fd, &msg, 0);
00935 #else
00936 bytes_written = write (server_fd, buf, 1);
00937 #endif
00938
00939 if (bytes_written < 0 && errno == EINTR)
00940 goto again;
00941
00942 if (bytes_written < 0)
00943 {
00944 dbus_set_error (error, _dbus_error_from_errno (errno),
00945 "Failed to write credentials byte: %s",
00946 _dbus_strerror (errno));
00947 return FALSE;
00948 }
00949 else if (bytes_written == 0)
00950 {
00951 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
00952 "wrote zero bytes writing credentials byte");
00953 return FALSE;
00954 }
00955 else
00956 {
00957 _dbus_assert (bytes_written == 1);
00958 _dbus_verbose ("wrote credentials byte\n");
00959 return TRUE;
00960 }
00961 }
00962
00984 dbus_bool_t
00985 _dbus_read_credentials_socket (int client_fd,
00986 DBusCredentials *credentials,
00987 DBusError *error)
00988 {
00989 struct msghdr msg;
00990 struct iovec iov;
00991 char buf;
00992 dbus_uid_t uid_read;
00993 dbus_pid_t pid_read;
00994 int bytes_read;
00995
00996 uid_read = DBUS_UID_UNSET;
00997 pid_read = DBUS_PID_UNSET;
00998
00999 #ifdef HAVE_CMSGCRED
01000 struct {
01001 struct cmsghdr hdr;
01002 struct cmsgcred cred;
01003 } cmsg;
01004
01005 #elif defined(LOCAL_CREDS)
01006 struct {
01007 struct cmsghdr hdr;
01008 struct sockcred cred;
01009 } cmsg;
01010 #endif
01011
01012 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01013
01014
01015
01016
01017
01018 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01019 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01020 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01021
01022 _dbus_credentials_clear (credentials);
01023
01024
01025
01026
01027
01028
01029
01030 iov.iov_base = &buf;
01031 iov.iov_len = 1;
01032
01033 memset (&msg, 0, sizeof (msg));
01034 msg.msg_iov = &iov;
01035 msg.msg_iovlen = 1;
01036
01037 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01038 memset (&cmsg, 0, sizeof (cmsg));
01039 msg.msg_control = &cmsg;
01040 msg.msg_controllen = sizeof (cmsg);
01041 #endif
01042
01043 again:
01044 bytes_read = recvmsg (client_fd, &msg, 0);
01045
01046 if (bytes_read < 0)
01047 {
01048 if (errno == EINTR)
01049 goto again;
01050
01051
01052
01053
01054
01055
01056 dbus_set_error (error, _dbus_error_from_errno (errno),
01057 "Failed to read credentials byte: %s",
01058 _dbus_strerror (errno));
01059 return FALSE;
01060 }
01061 else if (bytes_read == 0)
01062 {
01063
01064
01065
01066 dbus_set_error (error, DBUS_ERROR_FAILED,
01067 "Failed to read credentials byte (zero-length read)");
01068 return FALSE;
01069 }
01070 else if (buf != '\0')
01071 {
01072 dbus_set_error (error, DBUS_ERROR_FAILED,
01073 "Credentials byte was not nul");
01074 return FALSE;
01075 }
01076
01077 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01078 if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
01079 {
01080 dbus_set_error (error, DBUS_ERROR_FAILED,
01081 "Message from recvmsg() was not SCM_CREDS");
01082 return FALSE;
01083 }
01084 #endif
01085
01086 _dbus_verbose ("read credentials byte\n");
01087
01088 {
01089 #ifdef SO_PEERCRED
01090 struct ucred cr;
01091 int cr_len = sizeof (cr);
01092
01093 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01094 cr_len == sizeof (cr))
01095 {
01096 pid_read = cr.pid;
01097 uid_read = cr.uid;
01098 }
01099 else
01100 {
01101 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01102 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01103 }
01104 #elif defined(HAVE_CMSGCRED)
01105 pid_read = cmsg.cred.cmcred_pid;
01106 uid_read = cmsg.cred.cmcred_euid;
01107 #elif defined(LOCAL_CREDS)
01108 pid_read = DBUS_PID_UNSET;
01109 uid_read = cmsg.cred.sc_uid;
01110
01111
01112 _dbus_set_local_creds (client_fd, FALSE);
01113 #elif defined(HAVE_GETPEEREID)
01114 uid_t euid;
01115 gid_t egid;
01116 if (getpeereid (client_fd, &euid, &egid) == 0)
01117 {
01118 uid_read = euid;
01119 }
01120 else
01121 {
01122 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01123 }
01124 #elif defined(HAVE_GETPEERUCRED)
01125 ucred_t * ucred = NULL;
01126 if (getpeerucred (client_fd, &ucred) == 0)
01127 {
01128 pid_read = ucred_getpid (ucred);
01129 uid_read = ucred_geteuid (ucred);
01130 }
01131 else
01132 {
01133 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01134 }
01135 if (ucred != NULL)
01136 ucred_free (ucred);
01137 #else
01138 _dbus_verbose ("Socket credentials not supported on this OS\n");
01139 #endif
01140 }
01141
01142 _dbus_verbose ("Credentials:"
01143 " pid "DBUS_PID_FORMAT
01144 " uid "DBUS_UID_FORMAT
01145 "\n",
01146 pid_read,
01147 uid_read);
01148
01149 if (pid_read != DBUS_PID_UNSET)
01150 {
01151 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01152 {
01153 _DBUS_SET_OOM (error);
01154 return FALSE;
01155 }
01156 }
01157
01158 if (uid_read != DBUS_UID_UNSET)
01159 {
01160 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01161 {
01162 _DBUS_SET_OOM (error);
01163 return FALSE;
01164 }
01165 }
01166
01167 return TRUE;
01168 }
01169
01187 dbus_bool_t
01188 _dbus_send_credentials_socket (int server_fd,
01189 DBusError *error)
01190 {
01191 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01192
01193 if (write_credentials_byte (server_fd, error))
01194 return TRUE;
01195 else
01196 return FALSE;
01197 }
01198
01206 int
01207 _dbus_accept (int listen_fd)
01208 {
01209 int client_fd;
01210 struct sockaddr addr;
01211 socklen_t addrlen;
01212
01213 addrlen = sizeof (addr);
01214
01215 retry:
01216 client_fd = accept (listen_fd, &addr, &addrlen);
01217
01218 if (client_fd < 0)
01219 {
01220 if (errno == EINTR)
01221 goto retry;
01222 }
01223
01224 _dbus_verbose ("client fd %d accepted\n", client_fd);
01225
01226 return client_fd;
01227 }
01228
01237 dbus_bool_t
01238 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01239 {
01240 const char *directory;
01241 struct stat sb;
01242
01243 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01244
01245 directory = _dbus_string_get_const_data (dir);
01246
01247 if (stat (directory, &sb) < 0)
01248 {
01249 dbus_set_error (error, _dbus_error_from_errno (errno),
01250 "%s", _dbus_strerror (errno));
01251
01252 return FALSE;
01253 }
01254
01255 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01256 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01257 {
01258 dbus_set_error (error, DBUS_ERROR_FAILED,
01259 "%s directory is not private to the user", directory);
01260 return FALSE;
01261 }
01262
01263 return TRUE;
01264 }
01265
01266 static dbus_bool_t
01267 fill_user_info_from_passwd (struct passwd *p,
01268 DBusUserInfo *info,
01269 DBusError *error)
01270 {
01271 _dbus_assert (p->pw_name != NULL);
01272 _dbus_assert (p->pw_dir != NULL);
01273
01274 info->uid = p->pw_uid;
01275 info->primary_gid = p->pw_gid;
01276 info->username = _dbus_strdup (p->pw_name);
01277 info->homedir = _dbus_strdup (p->pw_dir);
01278
01279 if (info->username == NULL ||
01280 info->homedir == NULL)
01281 {
01282 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01283 return FALSE;
01284 }
01285
01286 return TRUE;
01287 }
01288
01289 static dbus_bool_t
01290 fill_user_info (DBusUserInfo *info,
01291 dbus_uid_t uid,
01292 const DBusString *username,
01293 DBusError *error)
01294 {
01295 const char *username_c;
01296
01297
01298 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01299 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01300
01301 info->uid = DBUS_UID_UNSET;
01302 info->primary_gid = DBUS_GID_UNSET;
01303 info->group_ids = NULL;
01304 info->n_group_ids = 0;
01305 info->username = NULL;
01306 info->homedir = NULL;
01307
01308 if (username != NULL)
01309 username_c = _dbus_string_get_const_data (username);
01310 else
01311 username_c = NULL;
01312
01313
01314
01315
01316
01317
01318 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01319 {
01320 struct passwd *p;
01321 int result;
01322 char buf[1024];
01323 struct passwd p_str;
01324
01325 p = NULL;
01326 #ifdef HAVE_POSIX_GETPWNAM_R
01327 if (uid != DBUS_UID_UNSET)
01328 result = getpwuid_r (uid, &p_str, buf, sizeof (buf),
01329 &p);
01330 else
01331 result = getpwnam_r (username_c, &p_str, buf, sizeof (buf),
01332 &p);
01333 #else
01334 if (uid != DBUS_UID_UNSET)
01335 p = getpwuid_r (uid, &p_str, buf, sizeof (buf));
01336 else
01337 p = getpwnam_r (username_c, &p_str, buf, sizeof (buf));
01338 result = 0;
01339 #endif
01340 if (result == 0 && p == &p_str)
01341 {
01342 if (!fill_user_info_from_passwd (p, info, error))
01343 return FALSE;
01344 }
01345 else
01346 {
01347 dbus_set_error (error, _dbus_error_from_errno (errno),
01348 "User \"%s\" unknown or no memory to allocate password entry\n",
01349 username_c ? username_c : "???");
01350 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
01351 return FALSE;
01352 }
01353 }
01354 #else
01355 {
01356
01357 struct passwd *p;
01358
01359 if (uid != DBUS_UID_UNSET)
01360 p = getpwuid (uid);
01361 else
01362 p = getpwnam (username_c);
01363
01364 if (p != NULL)
01365 {
01366 if (!fill_user_info_from_passwd (p, info, error))
01367 return FALSE;
01368 }
01369 else
01370 {
01371 dbus_set_error (error, _dbus_error_from_errno (errno),
01372 "User \"%s\" unknown or no memory to allocate password entry\n",
01373 username_c ? username_c : "???");
01374 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
01375 return FALSE;
01376 }
01377 }
01378 #endif
01379
01380
01381 username_c = info->username;
01382
01383 #ifdef HAVE_GETGROUPLIST
01384 {
01385 gid_t *buf;
01386 int buf_count;
01387 int i;
01388
01389 buf_count = 17;
01390 buf = dbus_new (gid_t, buf_count);
01391 if (buf == NULL)
01392 {
01393 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01394 goto failed;
01395 }
01396
01397 if (getgrouplist (username_c,
01398 info->primary_gid,
01399 buf, &buf_count) < 0)
01400 {
01401 gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
01402 if (new == NULL)
01403 {
01404 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01405 dbus_free (buf);
01406 goto failed;
01407 }
01408
01409 buf = new;
01410
01411 errno = 0;
01412 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
01413 {
01414 dbus_set_error (error,
01415 _dbus_error_from_errno (errno),
01416 "Failed to get groups for username \"%s\" primary GID "
01417 DBUS_GID_FORMAT ": %s\n",
01418 username_c, info->primary_gid,
01419 _dbus_strerror (errno));
01420 dbus_free (buf);
01421 goto failed;
01422 }
01423 }
01424
01425 info->group_ids = dbus_new (dbus_gid_t, buf_count);
01426 if (info->group_ids == NULL)
01427 {
01428 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01429 dbus_free (buf);
01430 goto failed;
01431 }
01432
01433 for (i = 0; i < buf_count; ++i)
01434 info->group_ids[i] = buf[i];
01435
01436 info->n_group_ids = buf_count;
01437
01438 dbus_free (buf);
01439 }
01440 #else
01441 {
01442
01443 info->group_ids = dbus_new (dbus_gid_t, 1);
01444 if (info->group_ids == NULL)
01445 {
01446 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01447 goto failed;
01448 }
01449
01450 info->n_group_ids = 1;
01451
01452 (info->group_ids)[0] = info->primary_gid;
01453 }
01454 #endif
01455
01456 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01457
01458 return TRUE;
01459
01460 failed:
01461 _DBUS_ASSERT_ERROR_IS_SET (error);
01462 return FALSE;
01463 }
01464
01473 dbus_bool_t
01474 _dbus_user_info_fill (DBusUserInfo *info,
01475 const DBusString *username,
01476 DBusError *error)
01477 {
01478 return fill_user_info (info, DBUS_UID_UNSET,
01479 username, error);
01480 }
01481
01490 dbus_bool_t
01491 _dbus_user_info_fill_uid (DBusUserInfo *info,
01492 dbus_uid_t uid,
01493 DBusError *error)
01494 {
01495 return fill_user_info (info, uid,
01496 NULL, error);
01497 }
01498
01506 dbus_bool_t
01507 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
01508 {
01509
01510
01511
01512
01513 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01514 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01515 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01516
01517 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
01518 return FALSE;
01519 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_getuid()))
01520 return FALSE;
01521
01522 return TRUE;
01523 }
01524
01536 dbus_bool_t
01537 _dbus_append_user_from_current_process (DBusString *str)
01538 {
01539 return _dbus_string_append_uint (str,
01540 _dbus_getuid ());
01541 }
01542
01547 dbus_pid_t
01548 _dbus_getpid (void)
01549 {
01550 return getpid ();
01551 }
01552
01556 dbus_uid_t
01557 _dbus_getuid (void)
01558 {
01559 return getuid ();
01560 }
01561
01568 unsigned long
01569 _dbus_pid_for_log (void)
01570 {
01571 return getpid ();
01572 }
01573
01581 dbus_bool_t
01582 _dbus_parse_uid (const DBusString *uid_str,
01583 dbus_uid_t *uid)
01584 {
01585 int end;
01586 long val;
01587
01588 if (_dbus_string_get_length (uid_str) == 0)
01589 {
01590 _dbus_verbose ("UID string was zero length\n");
01591 return FALSE;
01592 }
01593
01594 val = -1;
01595 end = 0;
01596 if (!_dbus_string_parse_int (uid_str, 0, &val,
01597 &end))
01598 {
01599 _dbus_verbose ("could not parse string as a UID\n");
01600 return FALSE;
01601 }
01602
01603 if (end != _dbus_string_get_length (uid_str))
01604 {
01605 _dbus_verbose ("string contained trailing stuff after UID\n");
01606 return FALSE;
01607 }
01608
01609 *uid = val;
01610
01611 return TRUE;
01612 }
01613
01614
01615 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
01616
01617 #ifdef DBUS_USE_ATOMIC_INT_486
01618
01619
01620 static inline dbus_int32_t
01621 atomic_exchange_and_add (DBusAtomic *atomic,
01622 volatile dbus_int32_t val)
01623 {
01624 register dbus_int32_t result;
01625
01626 __asm__ __volatile__ ("lock; xaddl %0,%1"
01627 : "=r" (result), "=m" (atomic->value)
01628 : "0" (val), "m" (atomic->value));
01629 return result;
01630 }
01631 #endif
01632
01641 dbus_int32_t
01642 _dbus_atomic_inc (DBusAtomic *atomic)
01643 {
01644 #ifdef DBUS_USE_ATOMIC_INT_486
01645 return atomic_exchange_and_add (atomic, 1);
01646 #else
01647 dbus_int32_t res;
01648 _DBUS_LOCK (atomic);
01649 res = atomic->value;
01650 atomic->value += 1;
01651 _DBUS_UNLOCK (atomic);
01652 return res;
01653 #endif
01654 }
01655
01664 dbus_int32_t
01665 _dbus_atomic_dec (DBusAtomic *atomic)
01666 {
01667 #ifdef DBUS_USE_ATOMIC_INT_486
01668 return atomic_exchange_and_add (atomic, -1);
01669 #else
01670 dbus_int32_t res;
01671
01672 _DBUS_LOCK (atomic);
01673 res = atomic->value;
01674 atomic->value -= 1;
01675 _DBUS_UNLOCK (atomic);
01676 return res;
01677 #endif
01678 }
01679
01680 #ifdef DBUS_BUILD_TESTS
01681
01684 dbus_gid_t
01685 _dbus_getgid (void)
01686 {
01687 return getgid ();
01688 }
01689 #endif
01690
01699 int
01700 _dbus_poll (DBusPollFD *fds,
01701 int n_fds,
01702 int timeout_milliseconds)
01703 {
01704 #ifdef HAVE_POLL
01705
01706
01707
01708
01709 if (_DBUS_POLLIN == POLLIN &&
01710 _DBUS_POLLPRI == POLLPRI &&
01711 _DBUS_POLLOUT == POLLOUT &&
01712 _DBUS_POLLERR == POLLERR &&
01713 _DBUS_POLLHUP == POLLHUP &&
01714 _DBUS_POLLNVAL == POLLNVAL &&
01715 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
01716 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
01717 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
01718 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
01719 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
01720 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
01721 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
01722 {
01723 return poll ((struct pollfd*) fds,
01724 n_fds,
01725 timeout_milliseconds);
01726 }
01727 else
01728 {
01729
01730
01731
01732 _dbus_warn ("didn't implement poll() properly for this system yet\n");
01733 return -1;
01734 }
01735 #else
01736
01737 fd_set read_set, write_set, err_set;
01738 int max_fd = 0;
01739 int i;
01740 struct timeval tv;
01741 int ready;
01742
01743 FD_ZERO (&read_set);
01744 FD_ZERO (&write_set);
01745 FD_ZERO (&err_set);
01746
01747 for (i = 0; i < n_fds; i++)
01748 {
01749 DBusPollFD *fdp = &fds[i];
01750
01751 if (fdp->events & _DBUS_POLLIN)
01752 FD_SET (fdp->fd, &read_set);
01753
01754 if (fdp->events & _DBUS_POLLOUT)
01755 FD_SET (fdp->fd, &write_set);
01756
01757 FD_SET (fdp->fd, &err_set);
01758
01759 max_fd = MAX (max_fd, fdp->fd);
01760 }
01761
01762 tv.tv_sec = timeout_milliseconds / 1000;
01763 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
01764
01765 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
01766 timeout_milliseconds < 0 ? NULL : &tv);
01767
01768 if (ready > 0)
01769 {
01770 for (i = 0; i < n_fds; i++)
01771 {
01772 DBusPollFD *fdp = &fds[i];
01773
01774 fdp->revents = 0;
01775
01776 if (FD_ISSET (fdp->fd, &read_set))
01777 fdp->revents |= _DBUS_POLLIN;
01778
01779 if (FD_ISSET (fdp->fd, &write_set))
01780 fdp->revents |= _DBUS_POLLOUT;
01781
01782 if (FD_ISSET (fdp->fd, &err_set))
01783 fdp->revents |= _DBUS_POLLERR;
01784 }
01785 }
01786
01787 return ready;
01788 #endif
01789 }
01790
01797 void
01798 _dbus_get_current_time (long *tv_sec,
01799 long *tv_usec)
01800 {
01801 struct timeval t;
01802
01803 gettimeofday (&t, NULL);
01804
01805 if (tv_sec)
01806 *tv_sec = t.tv_sec;
01807 if (tv_usec)
01808 *tv_usec = t.tv_usec;
01809 }
01810
01821 dbus_bool_t
01822 _dbus_file_get_contents (DBusString *str,
01823 const DBusString *filename,
01824 DBusError *error)
01825 {
01826 int fd;
01827 struct stat sb;
01828 int orig_len;
01829 int total;
01830 const char *filename_c;
01831
01832 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01833
01834 filename_c = _dbus_string_get_const_data (filename);
01835
01836
01837 fd = open (filename_c, O_RDONLY | O_BINARY);
01838 if (fd < 0)
01839 {
01840 dbus_set_error (error, _dbus_error_from_errno (errno),
01841 "Failed to open \"%s\": %s",
01842 filename_c,
01843 _dbus_strerror (errno));
01844 return FALSE;
01845 }
01846
01847 _dbus_verbose ("file fd %d opened\n", fd);
01848
01849 if (fstat (fd, &sb) < 0)
01850 {
01851 dbus_set_error (error, _dbus_error_from_errno (errno),
01852 "Failed to stat \"%s\": %s",
01853 filename_c,
01854 _dbus_strerror (errno));
01855
01856 _dbus_verbose ("fstat() failed: %s",
01857 _dbus_strerror (errno));
01858
01859 _dbus_close (fd, NULL);
01860
01861 return FALSE;
01862 }
01863
01864 if (sb.st_size > _DBUS_ONE_MEGABYTE)
01865 {
01866 dbus_set_error (error, DBUS_ERROR_FAILED,
01867 "File size %lu of \"%s\" is too large.",
01868 (unsigned long) sb.st_size, filename_c);
01869 _dbus_close (fd, NULL);
01870 return FALSE;
01871 }
01872
01873 total = 0;
01874 orig_len = _dbus_string_get_length (str);
01875 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
01876 {
01877 int bytes_read;
01878
01879 while (total < (int) sb.st_size)
01880 {
01881 bytes_read = _dbus_read (fd, str,
01882 sb.st_size - total);
01883 if (bytes_read <= 0)
01884 {
01885 dbus_set_error (error, _dbus_error_from_errno (errno),
01886 "Error reading \"%s\": %s",
01887 filename_c,
01888 _dbus_strerror (errno));
01889
01890 _dbus_verbose ("read() failed: %s",
01891 _dbus_strerror (errno));
01892
01893 _dbus_close (fd, NULL);
01894 _dbus_string_set_length (str, orig_len);
01895 return FALSE;
01896 }
01897 else
01898 total += bytes_read;
01899 }
01900
01901 _dbus_close (fd, NULL);
01902 return TRUE;
01903 }
01904 else if (sb.st_size != 0)
01905 {
01906 _dbus_verbose ("Can only open regular files at the moment.\n");
01907 dbus_set_error (error, DBUS_ERROR_FAILED,
01908 "\"%s\" is not a regular file",
01909 filename_c);
01910 _dbus_close (fd, NULL);
01911 return FALSE;
01912 }
01913 else
01914 {
01915 _dbus_close (fd, NULL);
01916 return TRUE;
01917 }
01918 }
01919
01929 dbus_bool_t
01930 _dbus_string_save_to_file (const DBusString *str,
01931 const DBusString *filename,
01932 DBusError *error)
01933 {
01934 int fd;
01935 int bytes_to_write;
01936 const char *filename_c;
01937 DBusString tmp_filename;
01938 const char *tmp_filename_c;
01939 int total;
01940 dbus_bool_t need_unlink;
01941 dbus_bool_t retval;
01942
01943 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01944
01945 fd = -1;
01946 retval = FALSE;
01947 need_unlink = FALSE;
01948
01949 if (!_dbus_string_init (&tmp_filename))
01950 {
01951 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01952 return FALSE;
01953 }
01954
01955 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
01956 {
01957 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01958 _dbus_string_free (&tmp_filename);
01959 return FALSE;
01960 }
01961
01962 if (!_dbus_string_append (&tmp_filename, "."))
01963 {
01964 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01965 _dbus_string_free (&tmp_filename);
01966 return FALSE;
01967 }
01968
01969 #define N_TMP_FILENAME_RANDOM_BYTES 8
01970 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
01971 {
01972 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01973 _dbus_string_free (&tmp_filename);
01974 return FALSE;
01975 }
01976
01977 filename_c = _dbus_string_get_const_data (filename);
01978 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
01979
01980 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
01981 0600);
01982 if (fd < 0)
01983 {
01984 dbus_set_error (error, _dbus_error_from_errno (errno),
01985 "Could not create %s: %s", tmp_filename_c,
01986 _dbus_strerror (errno));
01987 goto out;
01988 }
01989
01990 _dbus_verbose ("tmp file fd %d opened\n", fd);
01991
01992 need_unlink = TRUE;
01993
01994 total = 0;
01995 bytes_to_write = _dbus_string_get_length (str);
01996
01997 while (total < bytes_to_write)
01998 {
01999 int bytes_written;
02000
02001 bytes_written = _dbus_write (fd, str, total,
02002 bytes_to_write - total);
02003
02004 if (bytes_written <= 0)
02005 {
02006 dbus_set_error (error, _dbus_error_from_errno (errno),
02007 "Could not write to %s: %s", tmp_filename_c,
02008 _dbus_strerror (errno));
02009
02010 goto out;
02011 }
02012
02013 total += bytes_written;
02014 }
02015
02016 if (!_dbus_close (fd, NULL))
02017 {
02018 dbus_set_error (error, _dbus_error_from_errno (errno),
02019 "Could not close file %s: %s",
02020 tmp_filename_c, _dbus_strerror (errno));
02021
02022 goto out;
02023 }
02024
02025 fd = -1;
02026
02027 if (rename (tmp_filename_c, filename_c) < 0)
02028 {
02029 dbus_set_error (error, _dbus_error_from_errno (errno),
02030 "Could not rename %s to %s: %s",
02031 tmp_filename_c, filename_c,
02032 _dbus_strerror (errno));
02033
02034 goto out;
02035 }
02036
02037 need_unlink = FALSE;
02038
02039 retval = TRUE;
02040
02041 out:
02042
02043
02044
02045
02046 if (fd >= 0)
02047 _dbus_close (fd, NULL);
02048
02049 if (need_unlink && unlink (tmp_filename_c) < 0)
02050 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
02051 tmp_filename_c, _dbus_strerror (errno));
02052
02053 _dbus_string_free (&tmp_filename);
02054
02055 if (!retval)
02056 _DBUS_ASSERT_ERROR_IS_SET (error);
02057
02058 return retval;
02059 }
02060
02067 dbus_bool_t
02068 _dbus_make_file_world_readable(const DBusString *filename,
02069 DBusError *error)
02070 {
02071 const char *filename_c;
02072
02073 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02074
02075 filename_c = _dbus_string_get_const_data (filename);
02076 if (chmod (filename_c, 0644) == -1)
02077 {
02078 dbus_set_error (error,
02079 DBUS_ERROR_FAILED,
02080 "Could not change permissions of file %s: %s\n",
02081 filename_c,
02082 _dbus_strerror (errno));
02083 return FALSE;
02084 }
02085 return TRUE;
02086 }
02087
02094 dbus_bool_t
02095 _dbus_create_file_exclusively (const DBusString *filename,
02096 DBusError *error)
02097 {
02098 int fd;
02099 const char *filename_c;
02100
02101 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02102
02103 filename_c = _dbus_string_get_const_data (filename);
02104
02105 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
02106 0600);
02107 if (fd < 0)
02108 {
02109 dbus_set_error (error,
02110 DBUS_ERROR_FAILED,
02111 "Could not create file %s: %s\n",
02112 filename_c,
02113 _dbus_strerror (errno));
02114 return FALSE;
02115 }
02116
02117 _dbus_verbose ("exclusive file fd %d opened\n", fd);
02118
02119 if (!_dbus_close (fd, NULL))
02120 {
02121 dbus_set_error (error,
02122 DBUS_ERROR_FAILED,
02123 "Could not close file %s: %s\n",
02124 filename_c,
02125 _dbus_strerror (errno));
02126 return FALSE;
02127 }
02128
02129 return TRUE;
02130 }
02131
02140 dbus_bool_t
02141 _dbus_delete_file (const DBusString *filename,
02142 DBusError *error)
02143 {
02144 const char *filename_c;
02145
02146 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02147
02148 filename_c = _dbus_string_get_const_data (filename);
02149
02150 if (unlink (filename_c) < 0)
02151 {
02152 dbus_set_error (error, DBUS_ERROR_FAILED,
02153 "Failed to delete file %s: %s\n",
02154 filename_c, _dbus_strerror (errno));
02155 return FALSE;
02156 }
02157 else
02158 return TRUE;
02159 }
02160
02169 dbus_bool_t
02170 _dbus_create_directory (const DBusString *filename,
02171 DBusError *error)
02172 {
02173 const char *filename_c;
02174
02175 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02176
02177 filename_c = _dbus_string_get_const_data (filename);
02178
02179 if (mkdir (filename_c, 0700) < 0)
02180 {
02181 if (errno == EEXIST)
02182 return TRUE;
02183
02184 dbus_set_error (error, DBUS_ERROR_FAILED,
02185 "Failed to create directory %s: %s\n",
02186 filename_c, _dbus_strerror (errno));
02187 return FALSE;
02188 }
02189 else
02190 return TRUE;
02191 }
02192
02203 dbus_bool_t
02204 _dbus_concat_dir_and_file (DBusString *dir,
02205 const DBusString *next_component)
02206 {
02207 dbus_bool_t dir_ends_in_slash;
02208 dbus_bool_t file_starts_with_slash;
02209
02210 if (_dbus_string_get_length (dir) == 0 ||
02211 _dbus_string_get_length (next_component) == 0)
02212 return TRUE;
02213
02214 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02215 _dbus_string_get_length (dir) - 1);
02216
02217 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02218
02219 if (dir_ends_in_slash && file_starts_with_slash)
02220 {
02221 _dbus_string_shorten (dir, 1);
02222 }
02223 else if (!(dir_ends_in_slash || file_starts_with_slash))
02224 {
02225 if (!_dbus_string_append_byte (dir, '/'))
02226 return FALSE;
02227 }
02228
02229 return _dbus_string_copy (next_component, 0, dir,
02230 _dbus_string_get_length (dir));
02231 }
02232
02234 #define NANOSECONDS_PER_SECOND 1000000000
02235
02236 #define MICROSECONDS_PER_SECOND 1000000
02237
02238 #define MILLISECONDS_PER_SECOND 1000
02239
02240 #define NANOSECONDS_PER_MILLISECOND 1000000
02241
02242 #define MICROSECONDS_PER_MILLISECOND 1000
02243
02248 void
02249 _dbus_sleep_milliseconds (int milliseconds)
02250 {
02251 #ifdef HAVE_NANOSLEEP
02252 struct timespec req;
02253 struct timespec rem;
02254
02255 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02256 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02257 rem.tv_sec = 0;
02258 rem.tv_nsec = 0;
02259
02260 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02261 req = rem;
02262 #elif defined (HAVE_USLEEP)
02263 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02264 #else
02265 sleep (MAX (milliseconds / 1000, 1));
02266 #endif
02267 }
02268
02269 static dbus_bool_t
02270 _dbus_generate_pseudorandom_bytes (DBusString *str,
02271 int n_bytes)
02272 {
02273 int old_len;
02274 char *p;
02275
02276 old_len = _dbus_string_get_length (str);
02277
02278 if (!_dbus_string_lengthen (str, n_bytes))
02279 return FALSE;
02280
02281 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02282
02283 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02284
02285 return TRUE;
02286 }
02287
02296 dbus_bool_t
02297 _dbus_generate_random_bytes (DBusString *str,
02298 int n_bytes)
02299 {
02300 int old_len;
02301 int fd;
02302
02303
02304
02305
02306
02307
02308
02309 old_len = _dbus_string_get_length (str);
02310 fd = -1;
02311
02312
02313 fd = open ("/dev/urandom", O_RDONLY);
02314 if (fd < 0)
02315 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02316
02317 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02318
02319 if (_dbus_read (fd, str, n_bytes) != n_bytes)
02320 {
02321 _dbus_close (fd, NULL);
02322 _dbus_string_set_length (str, old_len);
02323 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02324 }
02325
02326 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02327 n_bytes);
02328
02329 _dbus_close (fd, NULL);
02330
02331 return TRUE;
02332 }
02333
02339 void
02340 _dbus_exit (int code)
02341 {
02342 _exit (code);
02343 }
02344
02353 const char*
02354 _dbus_strerror (int error_number)
02355 {
02356 const char *msg;
02357
02358 msg = strerror (error_number);
02359 if (msg == NULL)
02360 msg = "unknown";
02361
02362 return msg;
02363 }
02364
02368 void
02369 _dbus_disable_sigpipe (void)
02370 {
02371 signal (SIGPIPE, SIG_IGN);
02372 }
02373
02381 void
02382 _dbus_fd_set_close_on_exec (int fd)
02383 {
02384 int val;
02385
02386 val = fcntl (fd, F_GETFD, 0);
02387
02388 if (val < 0)
02389 return;
02390
02391 val |= FD_CLOEXEC;
02392
02393 fcntl (fd, F_SETFD, val);
02394 }
02395
02403 dbus_bool_t
02404 _dbus_close (int fd,
02405 DBusError *error)
02406 {
02407 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02408
02409 again:
02410 if (close (fd) < 0)
02411 {
02412 if (errno == EINTR)
02413 goto again;
02414
02415 dbus_set_error (error, _dbus_error_from_errno (errno),
02416 "Could not close fd %d", fd);
02417 return FALSE;
02418 }
02419
02420 return TRUE;
02421 }
02422
02430 dbus_bool_t
02431 _dbus_set_fd_nonblocking (int fd,
02432 DBusError *error)
02433 {
02434 int val;
02435
02436 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02437
02438 val = fcntl (fd, F_GETFL, 0);
02439 if (val < 0)
02440 {
02441 dbus_set_error (error, _dbus_error_from_errno (errno),
02442 "Failed to get flags from file descriptor %d: %s",
02443 fd, _dbus_strerror (errno));
02444 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02445 _dbus_strerror (errno));
02446 return FALSE;
02447 }
02448
02449 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02450 {
02451 dbus_set_error (error, _dbus_error_from_errno (errno),
02452 "Failed to set nonblocking flag of file descriptor %d: %s",
02453 fd, _dbus_strerror (errno));
02454 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02455 fd, _dbus_strerror (errno));
02456
02457 return FALSE;
02458 }
02459
02460 return TRUE;
02461 }
02462
02468 void
02469 _dbus_print_backtrace (void)
02470 {
02471 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02472 void *bt[500];
02473 int bt_size;
02474 int i;
02475 char **syms;
02476
02477 bt_size = backtrace (bt, 500);
02478
02479 syms = backtrace_symbols (bt, bt_size);
02480
02481 i = 0;
02482 while (i < bt_size)
02483 {
02484
02485 fprintf (stderr, " %s\n", syms[i]);
02486 ++i;
02487 }
02488 fflush (stderr);
02489
02490 free (syms);
02491 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02492 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
02493 #else
02494 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02495 #endif
02496 }
02497
02513 dbus_bool_t
02514 _dbus_full_duplex_pipe (int *fd1,
02515 int *fd2,
02516 dbus_bool_t blocking,
02517 DBusError *error)
02518 {
02519 #ifdef HAVE_SOCKETPAIR
02520 int fds[2];
02521
02522 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02523
02524 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
02525 {
02526 dbus_set_error (error, _dbus_error_from_errno (errno),
02527 "Could not create full-duplex pipe");
02528 return FALSE;
02529 }
02530
02531 if (!blocking &&
02532 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02533 !_dbus_set_fd_nonblocking (fds[1], NULL)))
02534 {
02535 dbus_set_error (error, _dbus_error_from_errno (errno),
02536 "Could not set full-duplex pipe nonblocking");
02537
02538 _dbus_close (fds[0], NULL);
02539 _dbus_close (fds[1], NULL);
02540
02541 return FALSE;
02542 }
02543
02544 *fd1 = fds[0];
02545 *fd2 = fds[1];
02546
02547 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02548 *fd1, *fd2);
02549
02550 return TRUE;
02551 #else
02552 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
02553 dbus_set_error (error, DBUS_ERROR_FAILED,
02554 "_dbus_full_duplex_pipe() not implemented on this OS");
02555 return FALSE;
02556 #endif
02557 }
02558
02559
02568 int
02569 _dbus_printf_string_upper_bound (const char *format,
02570 va_list args)
02571 {
02572 char c;
02573 return vsnprintf (&c, 1, format, args);
02574 }
02575
02582 const char*
02583 _dbus_get_tmpdir(void)
02584 {
02585 static const char* tmpdir = NULL;
02586
02587 if (tmpdir == NULL)
02588 {
02589
02590
02591
02592
02593 if (tmpdir == NULL)
02594 tmpdir = getenv("TMPDIR");
02595
02596
02597
02598
02599 if (tmpdir == NULL)
02600 tmpdir = getenv("TMP");
02601 if (tmpdir == NULL)
02602 tmpdir = getenv("TEMP");
02603
02604
02605 if (tmpdir == NULL)
02606 tmpdir = "/tmp";
02607 }
02608
02609 _dbus_assert(tmpdir != NULL);
02610
02611 return tmpdir;
02612 }
02613
02626 dbus_bool_t
02627 _dbus_get_autolaunch_address (DBusString *address,
02628 DBusError *error)
02629 {
02630 static char *argv[6];
02631 int address_pipe[2] = { -1, -1 };
02632 int errors_pipe[2] = { -1, -1 };
02633 pid_t pid;
02634 int ret;
02635 int status;
02636 int orig_len;
02637 int i;
02638 DBusString uuid;
02639 dbus_bool_t retval;
02640
02641 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02642 retval = FALSE;
02643
02644 _dbus_string_init (&uuid);
02645
02646 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
02647 {
02648 _DBUS_SET_OOM (error);
02649 goto out;
02650 }
02651
02652 i = 0;
02653 argv[i] = "dbus-launch";
02654 ++i;
02655 argv[i] = "--autolaunch";
02656 ++i;
02657 argv[i] = _dbus_string_get_data (&uuid);
02658 ++i;
02659 argv[i] = "--binary-syntax";
02660 ++i;
02661 argv[i] = "--close-stderr";
02662 ++i;
02663 argv[i] = NULL;
02664 ++i;
02665
02666 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
02667
02668 orig_len = _dbus_string_get_length (address);
02669
02670 #define READ_END 0
02671 #define WRITE_END 1
02672 if (pipe (address_pipe) < 0)
02673 {
02674 dbus_set_error (error, _dbus_error_from_errno (errno),
02675 "Failed to create a pipe: %s",
02676 _dbus_strerror (errno));
02677 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
02678 _dbus_strerror (errno));
02679 goto out;
02680 }
02681 if (pipe (errors_pipe) < 0)
02682 {
02683 dbus_set_error (error, _dbus_error_from_errno (errno),
02684 "Failed to create a pipe: %s",
02685 _dbus_strerror (errno));
02686 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
02687 _dbus_strerror (errno));
02688 goto out;
02689 }
02690
02691 pid = fork ();
02692 if (pid < 0)
02693 {
02694 dbus_set_error (error, _dbus_error_from_errno (errno),
02695 "Failed to fork(): %s",
02696 _dbus_strerror (errno));
02697 _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
02698 _dbus_strerror (errno));
02699 goto out;
02700 }
02701
02702 if (pid == 0)
02703 {
02704
02705 int fd = open ("/dev/null", O_RDWR);
02706 if (fd == -1)
02707
02708 _exit (1);
02709
02710 _dbus_verbose ("/dev/null fd %d opened\n", fd);
02711
02712
02713 close (address_pipe[READ_END]);
02714 close (errors_pipe[READ_END]);
02715 close (0);
02716 close (1);
02717 close (2);
02718
02719 if (dup2 (fd, 0) == -1)
02720 _exit (1);
02721 if (dup2 (address_pipe[WRITE_END], 1) == -1)
02722 _exit (1);
02723 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
02724 _exit (1);
02725
02726 close (fd);
02727 close (address_pipe[WRITE_END]);
02728 close (errors_pipe[WRITE_END]);
02729
02730 execv (DBUS_BINDIR "/dbus-launch", argv);
02731
02732
02733 execvp ("dbus-launch", argv);
02734
02735
02736 _exit (1);
02737 }
02738
02739
02740 close (address_pipe[WRITE_END]);
02741 close (errors_pipe[WRITE_END]);
02742 address_pipe[WRITE_END] = -1;
02743 errors_pipe[WRITE_END] = -1;
02744
02745 ret = 0;
02746 do
02747 {
02748 ret = _dbus_read (address_pipe[READ_END], address, 1024);
02749 }
02750 while (ret > 0);
02751
02752
02753 do
02754 {
02755 ret = waitpid (pid, &status, 0);
02756 }
02757 while (ret == -1 && errno == EINTR);
02758
02759
02760
02761 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
02762 _dbus_string_get_length (address) == orig_len)
02763 {
02764
02765 DBusString error_message;
02766 _dbus_string_init (&error_message);
02767 ret = 0;
02768 do
02769 {
02770 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
02771 }
02772 while (ret > 0);
02773
02774 _dbus_string_set_length (address, orig_len);
02775 if (_dbus_string_get_length (&error_message) > 0)
02776 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
02777 "dbus-launch failed to autolaunch D-Bus session: %s",
02778 _dbus_string_get_data (&error_message));
02779 else
02780 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
02781 "Failed to execute dbus-launch to autolaunch D-Bus session");
02782 goto out;
02783 }
02784
02785 retval = TRUE;
02786
02787 out:
02788 if (retval)
02789 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02790 else
02791 _DBUS_ASSERT_ERROR_IS_SET (error);
02792
02793 if (address_pipe[0] != -1)
02794 close (address_pipe[0]);
02795 if (address_pipe[1] != -1)
02796 close (address_pipe[1]);
02797 if (errors_pipe[0] != -1)
02798 close (errors_pipe[0]);
02799 if (errors_pipe[1] != -1)
02800 close (errors_pipe[1]);
02801
02802 _dbus_string_free (&uuid);
02803 return retval;
02804 }
02805
02824 dbus_bool_t
02825 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
02826 dbus_bool_t create_if_not_found,
02827 DBusError *error)
02828 {
02829 DBusString filename;
02830 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
02831 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
02832 }
02833
02834 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
02835
02836
02854 dbus_bool_t
02855 _dbus_get_standard_session_servicedirs (DBusList **dirs)
02856 {
02857 const char *xdg_data_home;
02858 const char *xdg_data_dirs;
02859 DBusString servicedir_path;
02860
02861 if (!_dbus_string_init (&servicedir_path))
02862 return FALSE;
02863
02864 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
02865 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
02866
02867 if (xdg_data_dirs != NULL)
02868 {
02869 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
02870 goto oom;
02871
02872 if (!_dbus_string_append (&servicedir_path, ":"))
02873 goto oom;
02874 }
02875 else
02876 {
02877 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
02878 goto oom;
02879 }
02880
02881
02882
02883
02884
02885
02886
02887 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
02888 goto oom;
02889
02890 if (xdg_data_home != NULL)
02891 {
02892 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
02893 goto oom;
02894 }
02895 else
02896 {
02897 const DBusString *homedir;
02898 DBusString local_share;
02899
02900 if (!_dbus_homedir_from_current_process (&homedir))
02901 goto oom;
02902
02903 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
02904 goto oom;
02905
02906 _dbus_string_init_const (&local_share, "/.local/share");
02907 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
02908 goto oom;
02909 }
02910
02911 if (!_dbus_split_paths_and_append (&servicedir_path,
02912 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
02913 dirs))
02914 goto oom;
02915
02916 _dbus_string_free (&servicedir_path);
02917 return TRUE;
02918
02919 oom:
02920 _dbus_string_free (&servicedir_path);
02921 return FALSE;
02922 }
02923
02932 dbus_bool_t
02933 _dbus_append_system_config_file (DBusString *str)
02934 {
02935 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
02936 }
02937
02944 dbus_bool_t
02945 _dbus_append_session_config_file (DBusString *str)
02946 {
02947 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
02948 }
02949
02957 void
02958 _dbus_flush_caches (void)
02959 {
02960 _dbus_user_database_flush_system ();
02961 }
02962
02976 dbus_bool_t
02977 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
02978 DBusCredentials *credentials)
02979 {
02980 DBusString homedir;
02981 DBusString dotdir;
02982 dbus_uid_t uid;
02983
02984 _dbus_assert (credentials != NULL);
02985 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
02986
02987 if (!_dbus_string_init (&homedir))
02988 return FALSE;
02989
02990 uid = _dbus_credentials_get_unix_uid (credentials);
02991 _dbus_assert (uid != DBUS_UID_UNSET);
02992
02993 if (!_dbus_homedir_from_uid (uid, &homedir))
02994 goto failed;
02995
02996 #ifdef DBUS_BUILD_TESTS
02997 {
02998 const char *override;
02999
03000 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03001 if (override != NULL && *override != '\0')
03002 {
03003 _dbus_string_set_length (&homedir, 0);
03004 if (!_dbus_string_append (&homedir, override))
03005 goto failed;
03006
03007 _dbus_verbose ("Using fake homedir for testing: %s\n",
03008 _dbus_string_get_const_data (&homedir));
03009 }
03010 else
03011 {
03012 static dbus_bool_t already_warned = FALSE;
03013 if (!already_warned)
03014 {
03015 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03016 already_warned = TRUE;
03017 }
03018 }
03019 }
03020 #endif
03021
03022 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03023 if (!_dbus_concat_dir_and_file (&homedir,
03024 &dotdir))
03025 goto failed;
03026
03027 if (!_dbus_string_copy (&homedir, 0,
03028 directory, _dbus_string_get_length (directory))) {
03029 goto failed;
03030 }
03031
03032 _dbus_string_free (&homedir);
03033 return TRUE;
03034
03035 failed:
03036 _dbus_string_free (&homedir);
03037 return FALSE;
03038 }
03039
03040
03047 dbus_bool_t
03048 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03049 {
03050 return errno == EAGAIN || errno == EWOULDBLOCK;
03051 }
03052
03053