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 #define _GNU_SOURCE
00026
00027 #include "dbus-internals.h"
00028 #include "dbus-sysdeps.h"
00029 #include "dbus-sysdeps-unix.h"
00030 #include "dbus-threads.h"
00031 #include "dbus-protocol.h"
00032 #include "dbus-transport.h"
00033 #include "dbus-string.h"
00034 #include "dbus-userdb.h"
00035 #include "dbus-list.h"
00036 #include "dbus-credentials.h"
00037
00038 #include <sys/types.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <signal.h>
00042 #include <unistd.h>
00043 #include <stdio.h>
00044 #include <fcntl.h>
00045 #include <sys/socket.h>
00046 #include <dirent.h>
00047 #include <sys/un.h>
00048 #include <pwd.h>
00049 #include <time.h>
00050 #include <locale.h>
00051 #include <sys/time.h>
00052 #include <sys/stat.h>
00053 #include <sys/wait.h>
00054 #include <netinet/in.h>
00055 #include <netdb.h>
00056 #include <grp.h>
00057
00058 #ifdef HAVE_ERRNO_H
00059 #include <errno.h>
00060 #endif
00061 #ifdef HAVE_WRITEV
00062 #include <sys/uio.h>
00063 #endif
00064 #ifdef HAVE_POLL
00065 #include <sys/poll.h>
00066 #endif
00067 #ifdef HAVE_BACKTRACE
00068 #include <execinfo.h>
00069 #endif
00070 #ifdef HAVE_GETPEERUCRED
00071 #include <ucred.h>
00072 #endif
00073
00074 #ifndef O_BINARY
00075 #define O_BINARY 0
00076 #endif
00077
00078 #ifndef HAVE_SOCKLEN_T
00079 #define socklen_t int
00080 #endif
00081
00082 static dbus_bool_t
00083 _dbus_open_socket (int *fd_p,
00084 int domain,
00085 int type,
00086 int protocol,
00087 DBusError *error)
00088 {
00089 *fd_p = socket (domain, type, protocol);
00090 if (*fd_p >= 0)
00091 {
00092 _dbus_verbose ("socket fd %d opened\n", *fd_p);
00093 return TRUE;
00094 }
00095 else
00096 {
00097 dbus_set_error(error,
00098 _dbus_error_from_errno (errno),
00099 "Failed to open socket: %s",
00100 _dbus_strerror (errno));
00101 return FALSE;
00102 }
00103 }
00104
00105 dbus_bool_t
00106 _dbus_open_tcp_socket (int *fd,
00107 DBusError *error)
00108 {
00109 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
00110 }
00111
00119 dbus_bool_t
00120 _dbus_open_unix_socket (int *fd,
00121 DBusError *error)
00122 {
00123 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00124 }
00125
00134 dbus_bool_t
00135 _dbus_close_socket (int fd,
00136 DBusError *error)
00137 {
00138 return _dbus_close (fd, error);
00139 }
00140
00150 int
00151 _dbus_read_socket (int fd,
00152 DBusString *buffer,
00153 int count)
00154 {
00155 return _dbus_read (fd, buffer, count);
00156 }
00157
00168 int
00169 _dbus_write_socket (int fd,
00170 const DBusString *buffer,
00171 int start,
00172 int len)
00173 {
00174 return _dbus_write (fd, buffer, start, len);
00175 }
00176
00187 int
00188 _dbus_pipe_write (DBusPipe *pipe,
00189 const DBusString *buffer,
00190 int start,
00191 int len,
00192 DBusError *error)
00193 {
00194 int written;
00195
00196 written = _dbus_write (pipe->fd_or_handle, buffer, start, len);
00197 if (written < 0)
00198 {
00199 dbus_set_error (error, DBUS_ERROR_FAILED,
00200 "Writing to pipe: %s\n",
00201 _dbus_strerror (errno));
00202 }
00203 return written;
00204 }
00205
00213 int
00214 _dbus_pipe_close (DBusPipe *pipe,
00215 DBusError *error)
00216 {
00217 if (_dbus_close (pipe->fd_or_handle, error) < 0)
00218 {
00219 return -1;
00220 }
00221 else
00222 {
00223 _dbus_pipe_invalidate (pipe);
00224 return 0;
00225 }
00226 }
00227
00241 int
00242 _dbus_write_socket_two (int fd,
00243 const DBusString *buffer1,
00244 int start1,
00245 int len1,
00246 const DBusString *buffer2,
00247 int start2,
00248 int len2)
00249 {
00250 return _dbus_write_two (fd, buffer1, start1, len1,
00251 buffer2, start2, len2);
00252 }
00253
00254
00271 int
00272 _dbus_read (int fd,
00273 DBusString *buffer,
00274 int count)
00275 {
00276 int bytes_read;
00277 int start;
00278 char *data;
00279
00280 _dbus_assert (count >= 0);
00281
00282 start = _dbus_string_get_length (buffer);
00283
00284 if (!_dbus_string_lengthen (buffer, count))
00285 {
00286 errno = ENOMEM;
00287 return -1;
00288 }
00289
00290 data = _dbus_string_get_data_len (buffer, start, count);
00291
00292 again:
00293
00294 bytes_read = read (fd, data, count);
00295
00296 if (bytes_read < 0)
00297 {
00298 if (errno == EINTR)
00299 goto again;
00300 else
00301 {
00302
00303 _dbus_string_set_length (buffer, start);
00304 return -1;
00305 }
00306 }
00307 else
00308 {
00309
00310 _dbus_string_set_length (buffer, start + bytes_read);
00311
00312 #if 0
00313 if (bytes_read > 0)
00314 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00315 #endif
00316
00317 return bytes_read;
00318 }
00319 }
00320
00331 int
00332 _dbus_write (int fd,
00333 const DBusString *buffer,
00334 int start,
00335 int len)
00336 {
00337 const char *data;
00338 int bytes_written;
00339
00340 data = _dbus_string_get_const_data_len (buffer, start, len);
00341
00342 again:
00343
00344 bytes_written = write (fd, data, len);
00345
00346 if (bytes_written < 0 && errno == EINTR)
00347 goto again;
00348
00349 #if 0
00350 if (bytes_written > 0)
00351 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00352 #endif
00353
00354 return bytes_written;
00355 }
00356
00377 int
00378 _dbus_write_two (int fd,
00379 const DBusString *buffer1,
00380 int start1,
00381 int len1,
00382 const DBusString *buffer2,
00383 int start2,
00384 int len2)
00385 {
00386 _dbus_assert (buffer1 != NULL);
00387 _dbus_assert (start1 >= 0);
00388 _dbus_assert (start2 >= 0);
00389 _dbus_assert (len1 >= 0);
00390 _dbus_assert (len2 >= 0);
00391
00392 #ifdef HAVE_WRITEV
00393 {
00394 struct iovec vectors[2];
00395 const char *data1;
00396 const char *data2;
00397 int bytes_written;
00398
00399 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00400
00401 if (buffer2 != NULL)
00402 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00403 else
00404 {
00405 data2 = NULL;
00406 start2 = 0;
00407 len2 = 0;
00408 }
00409
00410 vectors[0].iov_base = (char*) data1;
00411 vectors[0].iov_len = len1;
00412 vectors[1].iov_base = (char*) data2;
00413 vectors[1].iov_len = len2;
00414
00415 again:
00416
00417 bytes_written = writev (fd,
00418 vectors,
00419 data2 ? 2 : 1);
00420
00421 if (bytes_written < 0 && errno == EINTR)
00422 goto again;
00423
00424 return bytes_written;
00425 }
00426 #else
00427 {
00428 int ret1;
00429
00430 ret1 = _dbus_write (fd, buffer1, start1, len1);
00431 if (ret1 == len1 && buffer2 != NULL)
00432 {
00433 ret2 = _dbus_write (fd, buffer2, start2, len2);
00434 if (ret2 < 0)
00435 ret2 = 0;
00436
00437 return ret1 + ret2;
00438 }
00439 else
00440 return ret1;
00441 }
00442 #endif
00443 }
00444
00445 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00446
00474 int
00475 _dbus_connect_unix_socket (const char *path,
00476 dbus_bool_t abstract,
00477 DBusError *error)
00478 {
00479 int fd;
00480 size_t path_len;
00481 struct sockaddr_un addr;
00482
00483 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00484
00485 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00486 path, abstract);
00487
00488
00489 if (!_dbus_open_unix_socket (&fd, error))
00490 {
00491 _DBUS_ASSERT_ERROR_IS_SET(error);
00492 return -1;
00493 }
00494 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00495
00496 _DBUS_ZERO (addr);
00497 addr.sun_family = AF_UNIX;
00498 path_len = strlen (path);
00499
00500 if (abstract)
00501 {
00502 #ifdef HAVE_ABSTRACT_SOCKETS
00503 addr.sun_path[0] = '\0';
00504 path_len++;
00505
00506 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00507 {
00508 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00509 "Abstract socket name too long\n");
00510 _dbus_close (fd, NULL);
00511 return -1;
00512 }
00513
00514 strncpy (&addr.sun_path[1], path, path_len);
00515
00516 #else
00517 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00518 "Operating system does not support abstract socket namespace\n");
00519 _dbus_close (fd, NULL);
00520 return -1;
00521 #endif
00522 }
00523 else
00524 {
00525 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00526 {
00527 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00528 "Socket name too long\n");
00529 _dbus_close (fd, NULL);
00530 return -1;
00531 }
00532
00533 strncpy (addr.sun_path, path, path_len);
00534 }
00535
00536 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00537 {
00538 dbus_set_error (error,
00539 _dbus_error_from_errno (errno),
00540 "Failed to connect to socket %s: %s",
00541 path, _dbus_strerror (errno));
00542
00543 _dbus_close (fd, NULL);
00544 fd = -1;
00545
00546 return -1;
00547 }
00548
00549 if (!_dbus_set_fd_nonblocking (fd, error))
00550 {
00551 _DBUS_ASSERT_ERROR_IS_SET (error);
00552
00553 _dbus_close (fd, NULL);
00554 fd = -1;
00555
00556 return -1;
00557 }
00558
00559 return fd;
00560 }
00561
00571 static dbus_bool_t
00572 _dbus_set_local_creds (int fd, dbus_bool_t on)
00573 {
00574 dbus_bool_t retval = TRUE;
00575
00576 #if defined(HAVE_CMSGCRED)
00577
00578
00579
00580 #elif defined(LOCAL_CREDS)
00581 int val = on ? 1 : 0;
00582 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00583 {
00584 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00585 retval = FALSE;
00586 }
00587 else
00588 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00589 on ? "enabled" : "disabled", fd);
00590 #endif
00591
00592 return retval;
00593 }
00594
00610 int
00611 _dbus_listen_unix_socket (const char *path,
00612 dbus_bool_t abstract,
00613 DBusError *error)
00614 {
00615 int listen_fd;
00616 struct sockaddr_un addr;
00617 size_t path_len;
00618
00619 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00620
00621 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00622 path, abstract);
00623
00624 if (!_dbus_open_unix_socket (&listen_fd, error))
00625 {
00626 _DBUS_ASSERT_ERROR_IS_SET(error);
00627 return -1;
00628 }
00629 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00630
00631 _DBUS_ZERO (addr);
00632 addr.sun_family = AF_UNIX;
00633 path_len = strlen (path);
00634
00635 if (abstract)
00636 {
00637 #ifdef HAVE_ABSTRACT_SOCKETS
00638
00639
00640
00641 addr.sun_path[0] = '\0';
00642 path_len++;
00643
00644 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00645 {
00646 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00647 "Abstract socket name too long\n");
00648 _dbus_close (listen_fd, NULL);
00649 return -1;
00650 }
00651
00652 strncpy (&addr.sun_path[1], path, path_len);
00653
00654 #else
00655 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00656 "Operating system does not support abstract socket namespace\n");
00657 _dbus_close (listen_fd, NULL);
00658 return -1;
00659 #endif
00660 }
00661 else
00662 {
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673 {
00674 struct stat sb;
00675
00676 if (stat (path, &sb) == 0 &&
00677 S_ISSOCK (sb.st_mode))
00678 unlink (path);
00679 }
00680
00681 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00682 {
00683 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00684 "Abstract socket name too long\n");
00685 _dbus_close (listen_fd, NULL);
00686 return -1;
00687 }
00688
00689 strncpy (addr.sun_path, path, path_len);
00690 }
00691
00692 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00693 {
00694 dbus_set_error (error, _dbus_error_from_errno (errno),
00695 "Failed to bind socket \"%s\": %s",
00696 path, _dbus_strerror (errno));
00697 _dbus_close (listen_fd, NULL);
00698 return -1;
00699 }
00700
00701 if (listen (listen_fd, 30 ) < 0)
00702 {
00703 dbus_set_error (error, _dbus_error_from_errno (errno),
00704 "Failed to listen on socket \"%s\": %s",
00705 path, _dbus_strerror (errno));
00706 _dbus_close (listen_fd, NULL);
00707 return -1;
00708 }
00709
00710 if (!_dbus_set_local_creds (listen_fd, TRUE))
00711 {
00712 dbus_set_error (error, _dbus_error_from_errno (errno),
00713 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
00714 path, _dbus_strerror (errno));
00715 close (listen_fd);
00716 return -1;
00717 }
00718
00719 if (!_dbus_set_fd_nonblocking (listen_fd, error))
00720 {
00721 _DBUS_ASSERT_ERROR_IS_SET (error);
00722 _dbus_close (listen_fd, NULL);
00723 return -1;
00724 }
00725
00726
00727
00728
00729 if (!abstract && chmod (path, 0777) < 0)
00730 _dbus_warn ("Could not set mode 0777 on socket %s\n",
00731 path);
00732
00733 return listen_fd;
00734 }
00735
00747 int
00748 _dbus_connect_tcp_socket (const char *host,
00749 const char *port,
00750 const char *family,
00751 DBusError *error)
00752 {
00753 int fd = -1, res;
00754 struct addrinfo hints;
00755 struct addrinfo *ai, *tmp;
00756
00757 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00758
00759 if (!_dbus_open_tcp_socket (&fd, error))
00760 {
00761 _DBUS_ASSERT_ERROR_IS_SET(error);
00762 return -1;
00763 }
00764
00765 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00766
00767 _DBUS_ZERO (hints);
00768
00769 if (!family)
00770 hints.ai_family = AF_UNSPEC;
00771 else if (!strcmp(family, "ipv4"))
00772 hints.ai_family = AF_INET;
00773 else if (!strcmp(family, "ipv6"))
00774 hints.ai_family = AF_INET6;
00775 else
00776 {
00777 dbus_set_error (error,
00778 _dbus_error_from_errno (errno),
00779 "Unknown address family %s", family);
00780 return -1;
00781 }
00782 hints.ai_protocol = IPPROTO_TCP;
00783 hints.ai_socktype = SOCK_STREAM;
00784 hints.ai_flags = AI_ADDRCONFIG;
00785
00786 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
00787 {
00788 dbus_set_error (error,
00789 _dbus_error_from_errno (errno),
00790 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
00791 host, port, gai_strerror(res), res);
00792 _dbus_close (fd, NULL);
00793 return -1;
00794 }
00795
00796 tmp = ai;
00797 while (tmp)
00798 {
00799 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
00800 {
00801 freeaddrinfo(ai);
00802 _DBUS_ASSERT_ERROR_IS_SET(error);
00803 return -1;
00804 }
00805 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00806
00807 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
00808 {
00809 _dbus_close(fd, NULL);
00810 fd = -1;
00811 tmp = tmp->ai_next;
00812 continue;
00813 }
00814
00815 break;
00816 }
00817 freeaddrinfo(ai);
00818
00819 if (fd == -1)
00820 {
00821 dbus_set_error (error,
00822 _dbus_error_from_errno (errno),
00823 "Failed to connect to socket \"%s:%s\" %s",
00824 host, port, _dbus_strerror(errno));
00825 return -1;
00826 }
00827
00828
00829 if (!_dbus_set_fd_nonblocking (fd, error))
00830 {
00831 _dbus_close (fd, NULL);
00832 fd = -1;
00833
00834 return -1;
00835 }
00836
00837 return fd;
00838 }
00839
00854 int
00855 _dbus_listen_tcp_socket (const char *host,
00856 const char *port,
00857 const char *family,
00858 DBusString *retport,
00859 int **fds_p,
00860 DBusError *error)
00861 {
00862 int nlisten_fd = 0, *listen_fd = NULL, res, i;
00863 struct addrinfo hints;
00864 struct addrinfo *ai, *tmp;
00865
00866 *fds_p = NULL;
00867 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00868
00869 _DBUS_ZERO (hints);
00870
00871 if (!family)
00872 hints.ai_family = AF_UNSPEC;
00873 else if (!strcmp(family, "ipv4"))
00874 hints.ai_family = AF_INET;
00875 else if (!strcmp(family, "ipv6"))
00876 hints.ai_family = AF_INET6;
00877 else
00878 {
00879 dbus_set_error (error,
00880 _dbus_error_from_errno (errno),
00881 "Unknown address family %s", family);
00882 return -1;
00883 }
00884
00885 hints.ai_protocol = IPPROTO_TCP;
00886 hints.ai_socktype = SOCK_STREAM;
00887 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
00888
00889 redo_lookup_with_port:
00890 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
00891 {
00892 dbus_set_error (error,
00893 _dbus_error_from_errno (errno),
00894 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
00895 host ? host : "*", port, gai_strerror(res), res);
00896 return -1;
00897 }
00898
00899 tmp = ai;
00900 while (tmp)
00901 {
00902 int fd = -1, *newlisten_fd;
00903 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
00904 {
00905 _DBUS_ASSERT_ERROR_IS_SET(error);
00906 goto failed;
00907 }
00908 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00909
00910 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
00911 {
00912 _dbus_close(fd, NULL);
00913 if (errno == EADDRINUSE)
00914 {
00915
00916
00917
00918 tmp = tmp->ai_next;
00919 continue;
00920 }
00921 dbus_set_error (error, _dbus_error_from_errno (errno),
00922 "Failed to bind socket \"%s:%s\": %s",
00923 host ? host : "*", port, _dbus_strerror (errno));
00924 goto failed;
00925 }
00926
00927 if (listen (fd, 30 ) < 0)
00928 {
00929 _dbus_close (fd, NULL);
00930 dbus_set_error (error, _dbus_error_from_errno (errno),
00931 "Failed to listen on socket \"%s:%s\": %s",
00932 host ? host : "*", port, _dbus_strerror (errno));
00933 goto failed;
00934 }
00935
00936 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
00937 if (!newlisten_fd)
00938 {
00939 _dbus_close (fd, NULL);
00940 dbus_set_error (error, _dbus_error_from_errno (errno),
00941 "Failed to allocate file handle array: %s",
00942 _dbus_strerror (errno));
00943 goto failed;
00944 }
00945 listen_fd = newlisten_fd;
00946 listen_fd[nlisten_fd] = fd;
00947 nlisten_fd++;
00948
00949 if (!_dbus_string_get_length(retport))
00950 {
00951
00952
00953
00954
00955 if (!port || !strcmp(port, "0"))
00956 {
00957 struct sockaddr_storage addr;
00958 socklen_t addrlen;
00959 char portbuf[50];
00960
00961 addrlen = sizeof(addr);
00962 getsockname(fd, (struct sockaddr*) &addr, &addrlen);
00963
00964 if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
00965 portbuf, sizeof(portbuf),
00966 NI_NUMERICHOST)) != 0)
00967 {
00968 dbus_set_error (error, _dbus_error_from_errno (errno),
00969 "Failed to resolve port \"%s:%s\": %s (%s)",
00970 host ? host : "*", port, gai_strerror(res), res);
00971 goto failed;
00972 }
00973 if (!_dbus_string_append(retport, portbuf))
00974 {
00975 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00976 goto failed;
00977 }
00978
00979
00980 port = _dbus_string_get_const_data(retport);
00981 freeaddrinfo(ai);
00982 goto redo_lookup_with_port;
00983 }
00984 else
00985 {
00986 if (!_dbus_string_append(retport, port))
00987 {
00988 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00989 goto failed;
00990 }
00991 }
00992 }
00993
00994 tmp = tmp->ai_next;
00995 }
00996 freeaddrinfo(ai);
00997 ai = NULL;
00998
00999 if (!nlisten_fd)
01000 {
01001 errno = EADDRINUSE;
01002 dbus_set_error (error, _dbus_error_from_errno (errno),
01003 "Failed to bind socket \"%s:%s\": %s",
01004 host ? host : "*", port, _dbus_strerror (errno));
01005 return -1;
01006 }
01007
01008 for (i = 0 ; i < nlisten_fd ; i++)
01009 {
01010 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01011 {
01012 goto failed;
01013 }
01014 }
01015
01016 *fds_p = listen_fd;
01017
01018 return nlisten_fd;
01019
01020 failed:
01021 if (ai)
01022 freeaddrinfo(ai);
01023 for (i = 0 ; i < nlisten_fd ; i++)
01024 _dbus_close(listen_fd[i], NULL);
01025 dbus_free(listen_fd);
01026 return -1;
01027 }
01028
01029 static dbus_bool_t
01030 write_credentials_byte (int server_fd,
01031 DBusError *error)
01032 {
01033 int bytes_written;
01034 char buf[1] = { '\0' };
01035 #if defined(HAVE_CMSGCRED)
01036 struct {
01037 struct cmsghdr hdr;
01038 struct cmsgcred cred;
01039 } cmsg;
01040 struct iovec iov;
01041 struct msghdr msg;
01042 iov.iov_base = buf;
01043 iov.iov_len = 1;
01044
01045 memset (&msg, 0, sizeof (msg));
01046 msg.msg_iov = &iov;
01047 msg.msg_iovlen = 1;
01048
01049 msg.msg_control = &cmsg;
01050 msg.msg_controllen = sizeof (cmsg);
01051 memset (&cmsg, 0, sizeof (cmsg));
01052 cmsg.hdr.cmsg_len = sizeof (cmsg);
01053 cmsg.hdr.cmsg_level = SOL_SOCKET;
01054 cmsg.hdr.cmsg_type = SCM_CREDS;
01055 #endif
01056
01057 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01058
01059 again:
01060
01061 #if defined(HAVE_CMSGCRED)
01062 bytes_written = sendmsg (server_fd, &msg, 0);
01063 #else
01064 bytes_written = write (server_fd, buf, 1);
01065 #endif
01066
01067 if (bytes_written < 0 && errno == EINTR)
01068 goto again;
01069
01070 if (bytes_written < 0)
01071 {
01072 dbus_set_error (error, _dbus_error_from_errno (errno),
01073 "Failed to write credentials byte: %s",
01074 _dbus_strerror (errno));
01075 return FALSE;
01076 }
01077 else if (bytes_written == 0)
01078 {
01079 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01080 "wrote zero bytes writing credentials byte");
01081 return FALSE;
01082 }
01083 else
01084 {
01085 _dbus_assert (bytes_written == 1);
01086 _dbus_verbose ("wrote credentials byte\n");
01087 return TRUE;
01088 }
01089 }
01090
01112 dbus_bool_t
01113 _dbus_read_credentials_socket (int client_fd,
01114 DBusCredentials *credentials,
01115 DBusError *error)
01116 {
01117 struct msghdr msg;
01118 struct iovec iov;
01119 char buf;
01120 dbus_uid_t uid_read;
01121 dbus_pid_t pid_read;
01122 int bytes_read;
01123
01124 uid_read = DBUS_UID_UNSET;
01125 pid_read = DBUS_PID_UNSET;
01126
01127 #ifdef HAVE_CMSGCRED
01128 struct {
01129 struct cmsghdr hdr;
01130 struct cmsgcred cred;
01131 } cmsg;
01132
01133 #elif defined(LOCAL_CREDS)
01134 struct {
01135 struct cmsghdr hdr;
01136 struct sockcred cred;
01137 } cmsg;
01138 #endif
01139
01140 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01141
01142
01143
01144
01145
01146 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01147 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01148 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01149
01150 _dbus_credentials_clear (credentials);
01151
01152
01153
01154
01155
01156
01157
01158 iov.iov_base = &buf;
01159 iov.iov_len = 1;
01160
01161 memset (&msg, 0, sizeof (msg));
01162 msg.msg_iov = &iov;
01163 msg.msg_iovlen = 1;
01164
01165 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01166 memset (&cmsg, 0, sizeof (cmsg));
01167 msg.msg_control = &cmsg;
01168 msg.msg_controllen = sizeof (cmsg);
01169 #endif
01170
01171 again:
01172 bytes_read = recvmsg (client_fd, &msg, 0);
01173
01174 if (bytes_read < 0)
01175 {
01176 if (errno == EINTR)
01177 goto again;
01178
01179
01180
01181
01182
01183
01184 dbus_set_error (error, _dbus_error_from_errno (errno),
01185 "Failed to read credentials byte: %s",
01186 _dbus_strerror (errno));
01187 return FALSE;
01188 }
01189 else if (bytes_read == 0)
01190 {
01191
01192
01193
01194 dbus_set_error (error, DBUS_ERROR_FAILED,
01195 "Failed to read credentials byte (zero-length read)");
01196 return FALSE;
01197 }
01198 else if (buf != '\0')
01199 {
01200 dbus_set_error (error, DBUS_ERROR_FAILED,
01201 "Credentials byte was not nul");
01202 return FALSE;
01203 }
01204
01205 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01206 if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
01207 {
01208 dbus_set_error (error, DBUS_ERROR_FAILED,
01209 "Message from recvmsg() was not SCM_CREDS");
01210 return FALSE;
01211 }
01212 #endif
01213
01214 _dbus_verbose ("read credentials byte\n");
01215
01216 {
01217 #ifdef SO_PEERCRED
01218 struct ucred cr;
01219 int cr_len = sizeof (cr);
01220
01221 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01222 cr_len == sizeof (cr))
01223 {
01224 pid_read = cr.pid;
01225 uid_read = cr.uid;
01226 }
01227 else
01228 {
01229 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01230 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01231 }
01232 #elif defined(HAVE_CMSGCRED)
01233 pid_read = cmsg.cred.cmcred_pid;
01234 uid_read = cmsg.cred.cmcred_euid;
01235 #elif defined(LOCAL_CREDS)
01236 pid_read = DBUS_PID_UNSET;
01237 uid_read = cmsg.cred.sc_uid;
01238
01239
01240 _dbus_set_local_creds (client_fd, FALSE);
01241 #elif defined(HAVE_GETPEEREID)
01242 uid_t euid;
01243 gid_t egid;
01244 if (getpeereid (client_fd, &euid, &egid) == 0)
01245 {
01246 uid_read = euid;
01247 }
01248 else
01249 {
01250 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01251 }
01252 #elif defined(HAVE_GETPEERUCRED)
01253 ucred_t * ucred = NULL;
01254 if (getpeerucred (client_fd, &ucred) == 0)
01255 {
01256 pid_read = ucred_getpid (ucred);
01257 uid_read = ucred_geteuid (ucred);
01258 }
01259 else
01260 {
01261 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01262 }
01263 if (ucred != NULL)
01264 ucred_free (ucred);
01265 #else
01266 _dbus_verbose ("Socket credentials not supported on this OS\n");
01267 #endif
01268 }
01269
01270 _dbus_verbose ("Credentials:"
01271 " pid "DBUS_PID_FORMAT
01272 " uid "DBUS_UID_FORMAT
01273 "\n",
01274 pid_read,
01275 uid_read);
01276
01277 if (pid_read != DBUS_PID_UNSET)
01278 {
01279 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01280 {
01281 _DBUS_SET_OOM (error);
01282 return FALSE;
01283 }
01284 }
01285
01286 if (uid_read != DBUS_UID_UNSET)
01287 {
01288 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01289 {
01290 _DBUS_SET_OOM (error);
01291 return FALSE;
01292 }
01293 }
01294
01295 _dbus_credentials_add_unix_sid(credentials, client_fd);
01296
01297 return TRUE;
01298 }
01299
01317 dbus_bool_t
01318 _dbus_send_credentials_socket (int server_fd,
01319 DBusError *error)
01320 {
01321 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01322
01323 if (write_credentials_byte (server_fd, error))
01324 return TRUE;
01325 else
01326 return FALSE;
01327 }
01328
01336 int
01337 _dbus_accept (int listen_fd)
01338 {
01339 int client_fd;
01340 struct sockaddr addr;
01341 socklen_t addrlen;
01342
01343 addrlen = sizeof (addr);
01344
01345 retry:
01346 client_fd = accept (listen_fd, &addr, &addrlen);
01347
01348 if (client_fd < 0)
01349 {
01350 if (errno == EINTR)
01351 goto retry;
01352 }
01353
01354 _dbus_verbose ("client fd %d accepted\n", client_fd);
01355
01356 return client_fd;
01357 }
01358
01367 dbus_bool_t
01368 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01369 {
01370 const char *directory;
01371 struct stat sb;
01372
01373 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01374
01375 directory = _dbus_string_get_const_data (dir);
01376
01377 if (stat (directory, &sb) < 0)
01378 {
01379 dbus_set_error (error, _dbus_error_from_errno (errno),
01380 "%s", _dbus_strerror (errno));
01381
01382 return FALSE;
01383 }
01384
01385 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01386 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01387 {
01388 dbus_set_error (error, DBUS_ERROR_FAILED,
01389 "%s directory is not private to the user", directory);
01390 return FALSE;
01391 }
01392
01393 return TRUE;
01394 }
01395
01396 static dbus_bool_t
01397 fill_user_info_from_passwd (struct passwd *p,
01398 DBusUserInfo *info,
01399 DBusError *error)
01400 {
01401 _dbus_assert (p->pw_name != NULL);
01402 _dbus_assert (p->pw_dir != NULL);
01403
01404 info->uid = p->pw_uid;
01405 info->primary_gid = p->pw_gid;
01406 info->username = _dbus_strdup (p->pw_name);
01407 info->homedir = _dbus_strdup (p->pw_dir);
01408
01409 if (info->username == NULL ||
01410 info->homedir == NULL)
01411 {
01412 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01413 return FALSE;
01414 }
01415
01416 return TRUE;
01417 }
01418
01419 static dbus_bool_t
01420 fill_user_info (DBusUserInfo *info,
01421 dbus_uid_t uid,
01422 const DBusString *username,
01423 DBusError *error)
01424 {
01425 const char *username_c;
01426
01427
01428 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01429 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01430
01431 info->uid = DBUS_UID_UNSET;
01432 info->primary_gid = DBUS_GID_UNSET;
01433 info->group_ids = NULL;
01434 info->n_group_ids = 0;
01435 info->username = NULL;
01436 info->homedir = NULL;
01437
01438 if (username != NULL)
01439 username_c = _dbus_string_get_const_data (username);
01440 else
01441 username_c = NULL;
01442
01443
01444
01445
01446
01447
01448 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01449 {
01450 struct passwd *p;
01451 int result;
01452 char buf[1024];
01453 struct passwd p_str;
01454
01455 p = NULL;
01456 #ifdef HAVE_POSIX_GETPWNAM_R
01457 if (uid != DBUS_UID_UNSET)
01458 result = getpwuid_r (uid, &p_str, buf, sizeof (buf),
01459 &p);
01460 else
01461 result = getpwnam_r (username_c, &p_str, buf, sizeof (buf),
01462 &p);
01463 #else
01464 if (uid != DBUS_UID_UNSET)
01465 p = getpwuid_r (uid, &p_str, buf, sizeof (buf));
01466 else
01467 p = getpwnam_r (username_c, &p_str, buf, sizeof (buf));
01468 result = 0;
01469 #endif
01470 if (result == 0 && p == &p_str)
01471 {
01472 if (!fill_user_info_from_passwd (p, info, error))
01473 return FALSE;
01474 }
01475 else
01476 {
01477 dbus_set_error (error, _dbus_error_from_errno (errno),
01478 "User \"%s\" unknown or no memory to allocate password entry\n",
01479 username_c ? username_c : "???");
01480 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
01481 return FALSE;
01482 }
01483 }
01484 #else
01485 {
01486
01487 struct passwd *p;
01488
01489 if (uid != DBUS_UID_UNSET)
01490 p = getpwuid (uid);
01491 else
01492 p = getpwnam (username_c);
01493
01494 if (p != NULL)
01495 {
01496 if (!fill_user_info_from_passwd (p, info, error))
01497 return FALSE;
01498 }
01499 else
01500 {
01501 dbus_set_error (error, _dbus_error_from_errno (errno),
01502 "User \"%s\" unknown or no memory to allocate password entry\n",
01503 username_c ? username_c : "???");
01504 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
01505 return FALSE;
01506 }
01507 }
01508 #endif
01509
01510
01511 username_c = info->username;
01512
01513 #ifdef HAVE_GETGROUPLIST
01514 {
01515 gid_t *buf;
01516 int buf_count;
01517 int i;
01518
01519 buf_count = 17;
01520 buf = dbus_new (gid_t, buf_count);
01521 if (buf == NULL)
01522 {
01523 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01524 goto failed;
01525 }
01526
01527 if (getgrouplist (username_c,
01528 info->primary_gid,
01529 buf, &buf_count) < 0)
01530 {
01531 gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
01532 if (new == NULL)
01533 {
01534 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01535 dbus_free (buf);
01536 goto failed;
01537 }
01538
01539 buf = new;
01540
01541 errno = 0;
01542 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
01543 {
01544 dbus_set_error (error,
01545 _dbus_error_from_errno (errno),
01546 "Failed to get groups for username \"%s\" primary GID "
01547 DBUS_GID_FORMAT ": %s\n",
01548 username_c, info->primary_gid,
01549 _dbus_strerror (errno));
01550 dbus_free (buf);
01551 goto failed;
01552 }
01553 }
01554
01555 info->group_ids = dbus_new (dbus_gid_t, buf_count);
01556 if (info->group_ids == NULL)
01557 {
01558 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01559 dbus_free (buf);
01560 goto failed;
01561 }
01562
01563 for (i = 0; i < buf_count; ++i)
01564 info->group_ids[i] = buf[i];
01565
01566 info->n_group_ids = buf_count;
01567
01568 dbus_free (buf);
01569 }
01570 #else
01571 {
01572
01573 info->group_ids = dbus_new (dbus_gid_t, 1);
01574 if (info->group_ids == NULL)
01575 {
01576 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01577 goto failed;
01578 }
01579
01580 info->n_group_ids = 1;
01581
01582 (info->group_ids)[0] = info->primary_gid;
01583 }
01584 #endif
01585
01586 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01587
01588 return TRUE;
01589
01590 failed:
01591 _DBUS_ASSERT_ERROR_IS_SET (error);
01592 return FALSE;
01593 }
01594
01603 dbus_bool_t
01604 _dbus_user_info_fill (DBusUserInfo *info,
01605 const DBusString *username,
01606 DBusError *error)
01607 {
01608 return fill_user_info (info, DBUS_UID_UNSET,
01609 username, error);
01610 }
01611
01620 dbus_bool_t
01621 _dbus_user_info_fill_uid (DBusUserInfo *info,
01622 dbus_uid_t uid,
01623 DBusError *error)
01624 {
01625 return fill_user_info (info, uid,
01626 NULL, error);
01627 }
01628
01636 dbus_bool_t
01637 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
01638 {
01639
01640
01641
01642
01643 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01644 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01645 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01646
01647 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
01648 return FALSE;
01649 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
01650 return FALSE;
01651
01652 return TRUE;
01653 }
01654
01666 dbus_bool_t
01667 _dbus_append_user_from_current_process (DBusString *str)
01668 {
01669 return _dbus_string_append_uint (str,
01670 _dbus_geteuid ());
01671 }
01672
01677 dbus_pid_t
01678 _dbus_getpid (void)
01679 {
01680 return getpid ();
01681 }
01682
01686 dbus_uid_t
01687 _dbus_getuid (void)
01688 {
01689 return getuid ();
01690 }
01691
01695 dbus_uid_t
01696 _dbus_geteuid (void)
01697 {
01698 return geteuid ();
01699 }
01700
01707 unsigned long
01708 _dbus_pid_for_log (void)
01709 {
01710 return getpid ();
01711 }
01712
01720 dbus_bool_t
01721 _dbus_parse_uid (const DBusString *uid_str,
01722 dbus_uid_t *uid)
01723 {
01724 int end;
01725 long val;
01726
01727 if (_dbus_string_get_length (uid_str) == 0)
01728 {
01729 _dbus_verbose ("UID string was zero length\n");
01730 return FALSE;
01731 }
01732
01733 val = -1;
01734 end = 0;
01735 if (!_dbus_string_parse_int (uid_str, 0, &val,
01736 &end))
01737 {
01738 _dbus_verbose ("could not parse string as a UID\n");
01739 return FALSE;
01740 }
01741
01742 if (end != _dbus_string_get_length (uid_str))
01743 {
01744 _dbus_verbose ("string contained trailing stuff after UID\n");
01745 return FALSE;
01746 }
01747
01748 *uid = val;
01749
01750 return TRUE;
01751 }
01752
01753
01754 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
01755
01756 #if DBUS_USE_ATOMIC_INT_486_COND
01757
01758
01759 static inline dbus_int32_t
01760 atomic_exchange_and_add (DBusAtomic *atomic,
01761 volatile dbus_int32_t val)
01762 {
01763 register dbus_int32_t result;
01764
01765 __asm__ __volatile__ ("lock; xaddl %0,%1"
01766 : "=r" (result), "=m" (atomic->value)
01767 : "0" (val), "m" (atomic->value));
01768 return result;
01769 }
01770 #endif
01771
01780 dbus_int32_t
01781 _dbus_atomic_inc (DBusAtomic *atomic)
01782 {
01783 #if DBUS_USE_ATOMIC_INT_486_COND
01784 return atomic_exchange_and_add (atomic, 1);
01785 #else
01786 dbus_int32_t res;
01787 _DBUS_LOCK (atomic);
01788 res = atomic->value;
01789 atomic->value += 1;
01790 _DBUS_UNLOCK (atomic);
01791 return res;
01792 #endif
01793 }
01794
01803 dbus_int32_t
01804 _dbus_atomic_dec (DBusAtomic *atomic)
01805 {
01806 #if DBUS_USE_ATOMIC_INT_486_COND
01807 return atomic_exchange_and_add (atomic, -1);
01808 #else
01809 dbus_int32_t res;
01810
01811 _DBUS_LOCK (atomic);
01812 res = atomic->value;
01813 atomic->value -= 1;
01814 _DBUS_UNLOCK (atomic);
01815 return res;
01816 #endif
01817 }
01818
01819 #ifdef DBUS_BUILD_TESTS
01820
01823 dbus_gid_t
01824 _dbus_getgid (void)
01825 {
01826 return getgid ();
01827 }
01828 #endif
01829
01838 int
01839 _dbus_poll (DBusPollFD *fds,
01840 int n_fds,
01841 int timeout_milliseconds)
01842 {
01843 #ifdef HAVE_POLL
01844
01845
01846
01847
01848 if (_DBUS_POLLIN == POLLIN &&
01849 _DBUS_POLLPRI == POLLPRI &&
01850 _DBUS_POLLOUT == POLLOUT &&
01851 _DBUS_POLLERR == POLLERR &&
01852 _DBUS_POLLHUP == POLLHUP &&
01853 _DBUS_POLLNVAL == POLLNVAL &&
01854 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
01855 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
01856 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
01857 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
01858 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
01859 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
01860 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
01861 {
01862 return poll ((struct pollfd*) fds,
01863 n_fds,
01864 timeout_milliseconds);
01865 }
01866 else
01867 {
01868
01869
01870
01871 _dbus_warn ("didn't implement poll() properly for this system yet\n");
01872 return -1;
01873 }
01874 #else
01875
01876 fd_set read_set, write_set, err_set;
01877 int max_fd = 0;
01878 int i;
01879 struct timeval tv;
01880 int ready;
01881
01882 FD_ZERO (&read_set);
01883 FD_ZERO (&write_set);
01884 FD_ZERO (&err_set);
01885
01886 for (i = 0; i < n_fds; i++)
01887 {
01888 DBusPollFD *fdp = &fds[i];
01889
01890 if (fdp->events & _DBUS_POLLIN)
01891 FD_SET (fdp->fd, &read_set);
01892
01893 if (fdp->events & _DBUS_POLLOUT)
01894 FD_SET (fdp->fd, &write_set);
01895
01896 FD_SET (fdp->fd, &err_set);
01897
01898 max_fd = MAX (max_fd, fdp->fd);
01899 }
01900
01901 tv.tv_sec = timeout_milliseconds / 1000;
01902 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
01903
01904 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
01905 timeout_milliseconds < 0 ? NULL : &tv);
01906
01907 if (ready > 0)
01908 {
01909 for (i = 0; i < n_fds; i++)
01910 {
01911 DBusPollFD *fdp = &fds[i];
01912
01913 fdp->revents = 0;
01914
01915 if (FD_ISSET (fdp->fd, &read_set))
01916 fdp->revents |= _DBUS_POLLIN;
01917
01918 if (FD_ISSET (fdp->fd, &write_set))
01919 fdp->revents |= _DBUS_POLLOUT;
01920
01921 if (FD_ISSET (fdp->fd, &err_set))
01922 fdp->revents |= _DBUS_POLLERR;
01923 }
01924 }
01925
01926 return ready;
01927 #endif
01928 }
01929
01936 void
01937 _dbus_get_current_time (long *tv_sec,
01938 long *tv_usec)
01939 {
01940 struct timeval t;
01941
01942 gettimeofday (&t, NULL);
01943
01944 if (tv_sec)
01945 *tv_sec = t.tv_sec;
01946 if (tv_usec)
01947 *tv_usec = t.tv_usec;
01948 }
01949
01960 dbus_bool_t
01961 _dbus_file_get_contents (DBusString *str,
01962 const DBusString *filename,
01963 DBusError *error)
01964 {
01965 int fd;
01966 struct stat sb;
01967 int orig_len;
01968 int total;
01969 const char *filename_c;
01970
01971 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01972
01973 filename_c = _dbus_string_get_const_data (filename);
01974
01975
01976 fd = open (filename_c, O_RDONLY | O_BINARY);
01977 if (fd < 0)
01978 {
01979 dbus_set_error (error, _dbus_error_from_errno (errno),
01980 "Failed to open \"%s\": %s",
01981 filename_c,
01982 _dbus_strerror (errno));
01983 return FALSE;
01984 }
01985
01986 _dbus_verbose ("file fd %d opened\n", fd);
01987
01988 if (fstat (fd, &sb) < 0)
01989 {
01990 dbus_set_error (error, _dbus_error_from_errno (errno),
01991 "Failed to stat \"%s\": %s",
01992 filename_c,
01993 _dbus_strerror (errno));
01994
01995 _dbus_verbose ("fstat() failed: %s",
01996 _dbus_strerror (errno));
01997
01998 _dbus_close (fd, NULL);
01999
02000 return FALSE;
02001 }
02002
02003 if (sb.st_size > _DBUS_ONE_MEGABYTE)
02004 {
02005 dbus_set_error (error, DBUS_ERROR_FAILED,
02006 "File size %lu of \"%s\" is too large.",
02007 (unsigned long) sb.st_size, filename_c);
02008 _dbus_close (fd, NULL);
02009 return FALSE;
02010 }
02011
02012 total = 0;
02013 orig_len = _dbus_string_get_length (str);
02014 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
02015 {
02016 int bytes_read;
02017
02018 while (total < (int) sb.st_size)
02019 {
02020 bytes_read = _dbus_read (fd, str,
02021 sb.st_size - total);
02022 if (bytes_read <= 0)
02023 {
02024 dbus_set_error (error, _dbus_error_from_errno (errno),
02025 "Error reading \"%s\": %s",
02026 filename_c,
02027 _dbus_strerror (errno));
02028
02029 _dbus_verbose ("read() failed: %s",
02030 _dbus_strerror (errno));
02031
02032 _dbus_close (fd, NULL);
02033 _dbus_string_set_length (str, orig_len);
02034 return FALSE;
02035 }
02036 else
02037 total += bytes_read;
02038 }
02039
02040 _dbus_close (fd, NULL);
02041 return TRUE;
02042 }
02043 else if (sb.st_size != 0)
02044 {
02045 _dbus_verbose ("Can only open regular files at the moment.\n");
02046 dbus_set_error (error, DBUS_ERROR_FAILED,
02047 "\"%s\" is not a regular file",
02048 filename_c);
02049 _dbus_close (fd, NULL);
02050 return FALSE;
02051 }
02052 else
02053 {
02054 _dbus_close (fd, NULL);
02055 return TRUE;
02056 }
02057 }
02058
02068 dbus_bool_t
02069 _dbus_string_save_to_file (const DBusString *str,
02070 const DBusString *filename,
02071 DBusError *error)
02072 {
02073 int fd;
02074 int bytes_to_write;
02075 const char *filename_c;
02076 DBusString tmp_filename;
02077 const char *tmp_filename_c;
02078 int total;
02079 dbus_bool_t need_unlink;
02080 dbus_bool_t retval;
02081
02082 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02083
02084 fd = -1;
02085 retval = FALSE;
02086 need_unlink = FALSE;
02087
02088 if (!_dbus_string_init (&tmp_filename))
02089 {
02090 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02091 return FALSE;
02092 }
02093
02094 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
02095 {
02096 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02097 _dbus_string_free (&tmp_filename);
02098 return FALSE;
02099 }
02100
02101 if (!_dbus_string_append (&tmp_filename, "."))
02102 {
02103 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02104 _dbus_string_free (&tmp_filename);
02105 return FALSE;
02106 }
02107
02108 #define N_TMP_FILENAME_RANDOM_BYTES 8
02109 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
02110 {
02111 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02112 _dbus_string_free (&tmp_filename);
02113 return FALSE;
02114 }
02115
02116 filename_c = _dbus_string_get_const_data (filename);
02117 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
02118
02119 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
02120 0600);
02121 if (fd < 0)
02122 {
02123 dbus_set_error (error, _dbus_error_from_errno (errno),
02124 "Could not create %s: %s", tmp_filename_c,
02125 _dbus_strerror (errno));
02126 goto out;
02127 }
02128
02129 _dbus_verbose ("tmp file fd %d opened\n", fd);
02130
02131 need_unlink = TRUE;
02132
02133 total = 0;
02134 bytes_to_write = _dbus_string_get_length (str);
02135
02136 while (total < bytes_to_write)
02137 {
02138 int bytes_written;
02139
02140 bytes_written = _dbus_write (fd, str, total,
02141 bytes_to_write - total);
02142
02143 if (bytes_written <= 0)
02144 {
02145 dbus_set_error (error, _dbus_error_from_errno (errno),
02146 "Could not write to %s: %s", tmp_filename_c,
02147 _dbus_strerror (errno));
02148
02149 goto out;
02150 }
02151
02152 total += bytes_written;
02153 }
02154
02155 if (!_dbus_close (fd, NULL))
02156 {
02157 dbus_set_error (error, _dbus_error_from_errno (errno),
02158 "Could not close file %s: %s",
02159 tmp_filename_c, _dbus_strerror (errno));
02160
02161 goto out;
02162 }
02163
02164 fd = -1;
02165
02166 if (rename (tmp_filename_c, filename_c) < 0)
02167 {
02168 dbus_set_error (error, _dbus_error_from_errno (errno),
02169 "Could not rename %s to %s: %s",
02170 tmp_filename_c, filename_c,
02171 _dbus_strerror (errno));
02172
02173 goto out;
02174 }
02175
02176 need_unlink = FALSE;
02177
02178 retval = TRUE;
02179
02180 out:
02181
02182
02183
02184
02185 if (fd >= 0)
02186 _dbus_close (fd, NULL);
02187
02188 if (need_unlink && unlink (tmp_filename_c) < 0)
02189 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
02190 tmp_filename_c, _dbus_strerror (errno));
02191
02192 _dbus_string_free (&tmp_filename);
02193
02194 if (!retval)
02195 _DBUS_ASSERT_ERROR_IS_SET (error);
02196
02197 return retval;
02198 }
02199
02206 dbus_bool_t
02207 _dbus_make_file_world_readable(const DBusString *filename,
02208 DBusError *error)
02209 {
02210 const char *filename_c;
02211
02212 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02213
02214 filename_c = _dbus_string_get_const_data (filename);
02215 if (chmod (filename_c, 0644) == -1)
02216 {
02217 dbus_set_error (error,
02218 DBUS_ERROR_FAILED,
02219 "Could not change permissions of file %s: %s\n",
02220 filename_c,
02221 _dbus_strerror (errno));
02222 return FALSE;
02223 }
02224 return TRUE;
02225 }
02226
02233 dbus_bool_t
02234 _dbus_create_file_exclusively (const DBusString *filename,
02235 DBusError *error)
02236 {
02237 int fd;
02238 const char *filename_c;
02239
02240 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02241
02242 filename_c = _dbus_string_get_const_data (filename);
02243
02244 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
02245 0600);
02246 if (fd < 0)
02247 {
02248 dbus_set_error (error,
02249 DBUS_ERROR_FAILED,
02250 "Could not create file %s: %s\n",
02251 filename_c,
02252 _dbus_strerror (errno));
02253 return FALSE;
02254 }
02255
02256 _dbus_verbose ("exclusive file fd %d opened\n", fd);
02257
02258 if (!_dbus_close (fd, NULL))
02259 {
02260 dbus_set_error (error,
02261 DBUS_ERROR_FAILED,
02262 "Could not close file %s: %s\n",
02263 filename_c,
02264 _dbus_strerror (errno));
02265 return FALSE;
02266 }
02267
02268 return TRUE;
02269 }
02270
02279 dbus_bool_t
02280 _dbus_delete_file (const DBusString *filename,
02281 DBusError *error)
02282 {
02283 const char *filename_c;
02284
02285 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02286
02287 filename_c = _dbus_string_get_const_data (filename);
02288
02289 if (unlink (filename_c) < 0)
02290 {
02291 dbus_set_error (error, DBUS_ERROR_FAILED,
02292 "Failed to delete file %s: %s\n",
02293 filename_c, _dbus_strerror (errno));
02294 return FALSE;
02295 }
02296 else
02297 return TRUE;
02298 }
02299
02308 dbus_bool_t
02309 _dbus_create_directory (const DBusString *filename,
02310 DBusError *error)
02311 {
02312 const char *filename_c;
02313
02314 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02315
02316 filename_c = _dbus_string_get_const_data (filename);
02317
02318 if (mkdir (filename_c, 0700) < 0)
02319 {
02320 if (errno == EEXIST)
02321 return TRUE;
02322
02323 dbus_set_error (error, DBUS_ERROR_FAILED,
02324 "Failed to create directory %s: %s\n",
02325 filename_c, _dbus_strerror (errno));
02326 return FALSE;
02327 }
02328 else
02329 return TRUE;
02330 }
02331
02342 dbus_bool_t
02343 _dbus_concat_dir_and_file (DBusString *dir,
02344 const DBusString *next_component)
02345 {
02346 dbus_bool_t dir_ends_in_slash;
02347 dbus_bool_t file_starts_with_slash;
02348
02349 if (_dbus_string_get_length (dir) == 0 ||
02350 _dbus_string_get_length (next_component) == 0)
02351 return TRUE;
02352
02353 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02354 _dbus_string_get_length (dir) - 1);
02355
02356 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02357
02358 if (dir_ends_in_slash && file_starts_with_slash)
02359 {
02360 _dbus_string_shorten (dir, 1);
02361 }
02362 else if (!(dir_ends_in_slash || file_starts_with_slash))
02363 {
02364 if (!_dbus_string_append_byte (dir, '/'))
02365 return FALSE;
02366 }
02367
02368 return _dbus_string_copy (next_component, 0, dir,
02369 _dbus_string_get_length (dir));
02370 }
02371
02373 #define NANOSECONDS_PER_SECOND 1000000000
02374
02375 #define MICROSECONDS_PER_SECOND 1000000
02376
02377 #define MILLISECONDS_PER_SECOND 1000
02378
02379 #define NANOSECONDS_PER_MILLISECOND 1000000
02380
02381 #define MICROSECONDS_PER_MILLISECOND 1000
02382
02387 void
02388 _dbus_sleep_milliseconds (int milliseconds)
02389 {
02390 #ifdef HAVE_NANOSLEEP
02391 struct timespec req;
02392 struct timespec rem;
02393
02394 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02395 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02396 rem.tv_sec = 0;
02397 rem.tv_nsec = 0;
02398
02399 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02400 req = rem;
02401 #elif defined (HAVE_USLEEP)
02402 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02403 #else
02404 sleep (MAX (milliseconds / 1000, 1));
02405 #endif
02406 }
02407
02408 static dbus_bool_t
02409 _dbus_generate_pseudorandom_bytes (DBusString *str,
02410 int n_bytes)
02411 {
02412 int old_len;
02413 char *p;
02414
02415 old_len = _dbus_string_get_length (str);
02416
02417 if (!_dbus_string_lengthen (str, n_bytes))
02418 return FALSE;
02419
02420 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02421
02422 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02423
02424 return TRUE;
02425 }
02426
02435 dbus_bool_t
02436 _dbus_generate_random_bytes (DBusString *str,
02437 int n_bytes)
02438 {
02439 int old_len;
02440 int fd;
02441
02442
02443
02444
02445
02446
02447
02448 old_len = _dbus_string_get_length (str);
02449 fd = -1;
02450
02451
02452 fd = open ("/dev/urandom", O_RDONLY);
02453 if (fd < 0)
02454 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02455
02456 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02457
02458 if (_dbus_read (fd, str, n_bytes) != n_bytes)
02459 {
02460 _dbus_close (fd, NULL);
02461 _dbus_string_set_length (str, old_len);
02462 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02463 }
02464
02465 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02466 n_bytes);
02467
02468 _dbus_close (fd, NULL);
02469
02470 return TRUE;
02471 }
02472
02478 void
02479 _dbus_exit (int code)
02480 {
02481 _exit (code);
02482 }
02483
02492 const char*
02493 _dbus_strerror (int error_number)
02494 {
02495 const char *msg;
02496
02497 msg = strerror (error_number);
02498 if (msg == NULL)
02499 msg = "unknown";
02500
02501 return msg;
02502 }
02503
02507 void
02508 _dbus_disable_sigpipe (void)
02509 {
02510 signal (SIGPIPE, SIG_IGN);
02511 }
02512
02520 void
02521 _dbus_fd_set_close_on_exec (int fd)
02522 {
02523 int val;
02524
02525 val = fcntl (fd, F_GETFD, 0);
02526
02527 if (val < 0)
02528 return;
02529
02530 val |= FD_CLOEXEC;
02531
02532 fcntl (fd, F_SETFD, val);
02533 }
02534
02542 dbus_bool_t
02543 _dbus_close (int fd,
02544 DBusError *error)
02545 {
02546 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02547
02548 again:
02549 if (close (fd) < 0)
02550 {
02551 if (errno == EINTR)
02552 goto again;
02553
02554 dbus_set_error (error, _dbus_error_from_errno (errno),
02555 "Could not close fd %d", fd);
02556 return FALSE;
02557 }
02558
02559 return TRUE;
02560 }
02561
02569 dbus_bool_t
02570 _dbus_set_fd_nonblocking (int fd,
02571 DBusError *error)
02572 {
02573 int val;
02574
02575 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02576
02577 val = fcntl (fd, F_GETFL, 0);
02578 if (val < 0)
02579 {
02580 dbus_set_error (error, _dbus_error_from_errno (errno),
02581 "Failed to get flags from file descriptor %d: %s",
02582 fd, _dbus_strerror (errno));
02583 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02584 _dbus_strerror (errno));
02585 return FALSE;
02586 }
02587
02588 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02589 {
02590 dbus_set_error (error, _dbus_error_from_errno (errno),
02591 "Failed to set nonblocking flag of file descriptor %d: %s",
02592 fd, _dbus_strerror (errno));
02593 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02594 fd, _dbus_strerror (errno));
02595
02596 return FALSE;
02597 }
02598
02599 return TRUE;
02600 }
02601
02607 void
02608 _dbus_print_backtrace (void)
02609 {
02610 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02611 void *bt[500];
02612 int bt_size;
02613 int i;
02614 char **syms;
02615
02616 bt_size = backtrace (bt, 500);
02617
02618 syms = backtrace_symbols (bt, bt_size);
02619
02620 i = 0;
02621 while (i < bt_size)
02622 {
02623
02624 fprintf (stderr, " %s\n", syms[i]);
02625 ++i;
02626 }
02627 fflush (stderr);
02628
02629 free (syms);
02630 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02631 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
02632 #else
02633 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02634 #endif
02635 }
02636
02652 dbus_bool_t
02653 _dbus_full_duplex_pipe (int *fd1,
02654 int *fd2,
02655 dbus_bool_t blocking,
02656 DBusError *error)
02657 {
02658 #ifdef HAVE_SOCKETPAIR
02659 int fds[2];
02660
02661 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02662
02663 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
02664 {
02665 dbus_set_error (error, _dbus_error_from_errno (errno),
02666 "Could not create full-duplex pipe");
02667 return FALSE;
02668 }
02669
02670 if (!blocking &&
02671 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02672 !_dbus_set_fd_nonblocking (fds[1], NULL)))
02673 {
02674 dbus_set_error (error, _dbus_error_from_errno (errno),
02675 "Could not set full-duplex pipe nonblocking");
02676
02677 _dbus_close (fds[0], NULL);
02678 _dbus_close (fds[1], NULL);
02679
02680 return FALSE;
02681 }
02682
02683 *fd1 = fds[0];
02684 *fd2 = fds[1];
02685
02686 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02687 *fd1, *fd2);
02688
02689 return TRUE;
02690 #else
02691 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
02692 dbus_set_error (error, DBUS_ERROR_FAILED,
02693 "_dbus_full_duplex_pipe() not implemented on this OS");
02694 return FALSE;
02695 #endif
02696 }
02697
02698
02707 int
02708 _dbus_printf_string_upper_bound (const char *format,
02709 va_list args)
02710 {
02711 char c;
02712 return vsnprintf (&c, 1, format, args);
02713 }
02714
02721 const char*
02722 _dbus_get_tmpdir(void)
02723 {
02724 static const char* tmpdir = NULL;
02725
02726 if (tmpdir == NULL)
02727 {
02728
02729
02730
02731
02732 if (tmpdir == NULL)
02733 tmpdir = getenv("TMPDIR");
02734
02735
02736
02737
02738 if (tmpdir == NULL)
02739 tmpdir = getenv("TMP");
02740 if (tmpdir == NULL)
02741 tmpdir = getenv("TEMP");
02742
02743
02744 if (tmpdir == NULL)
02745 tmpdir = "/tmp";
02746 }
02747
02748 _dbus_assert(tmpdir != NULL);
02749
02750 return tmpdir;
02751 }
02752
02765 dbus_bool_t
02766 _dbus_get_autolaunch_address (DBusString *address,
02767 DBusError *error)
02768 {
02769 static char *argv[6];
02770 int address_pipe[2] = { -1, -1 };
02771 int errors_pipe[2] = { -1, -1 };
02772 pid_t pid;
02773 int ret;
02774 int status;
02775 int orig_len;
02776 int i;
02777 DBusString uuid;
02778 dbus_bool_t retval;
02779
02780 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02781 retval = FALSE;
02782
02783 if (!_dbus_string_init (&uuid))
02784 {
02785 _DBUS_SET_OOM (error);
02786 return FALSE;
02787 }
02788
02789 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
02790 {
02791 _DBUS_SET_OOM (error);
02792 goto out;
02793 }
02794
02795 i = 0;
02796 argv[i] = "dbus-launch";
02797 ++i;
02798 argv[i] = "--autolaunch";
02799 ++i;
02800 argv[i] = _dbus_string_get_data (&uuid);
02801 ++i;
02802 argv[i] = "--binary-syntax";
02803 ++i;
02804 argv[i] = "--close-stderr";
02805 ++i;
02806 argv[i] = NULL;
02807 ++i;
02808
02809 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
02810
02811 orig_len = _dbus_string_get_length (address);
02812
02813 #define READ_END 0
02814 #define WRITE_END 1
02815 if (pipe (address_pipe) < 0)
02816 {
02817 dbus_set_error (error, _dbus_error_from_errno (errno),
02818 "Failed to create a pipe: %s",
02819 _dbus_strerror (errno));
02820 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
02821 _dbus_strerror (errno));
02822 goto out;
02823 }
02824 if (pipe (errors_pipe) < 0)
02825 {
02826 dbus_set_error (error, _dbus_error_from_errno (errno),
02827 "Failed to create a pipe: %s",
02828 _dbus_strerror (errno));
02829 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
02830 _dbus_strerror (errno));
02831 goto out;
02832 }
02833
02834 pid = fork ();
02835 if (pid < 0)
02836 {
02837 dbus_set_error (error, _dbus_error_from_errno (errno),
02838 "Failed to fork(): %s",
02839 _dbus_strerror (errno));
02840 _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
02841 _dbus_strerror (errno));
02842 goto out;
02843 }
02844
02845 if (pid == 0)
02846 {
02847
02848 int maxfds = getdtablesize();
02849 int fd = open ("/dev/null", O_RDWR);
02850 if (fd == -1)
02851
02852 _exit (1);
02853
02854 _dbus_verbose ("/dev/null fd %d opened\n", fd);
02855
02856
02857 close (address_pipe[READ_END]);
02858 close (errors_pipe[READ_END]);
02859 close (0);
02860 close (1);
02861 close (2);
02862
02863 if (dup2 (fd, 0) == -1)
02864 _exit (1);
02865 if (dup2 (address_pipe[WRITE_END], 1) == -1)
02866 _exit (1);
02867 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
02868 _exit (1);
02869
02870
02871 for( i = 3; i<maxfds; i++)
02872 close(i);
02873
02874 execv (DBUS_BINDIR "/dbus-launch", argv);
02875
02876
02877 execvp ("dbus-launch", argv);
02878
02879
02880 _exit (1);
02881 }
02882
02883
02884 close (address_pipe[WRITE_END]);
02885 close (errors_pipe[WRITE_END]);
02886 address_pipe[WRITE_END] = -1;
02887 errors_pipe[WRITE_END] = -1;
02888
02889 ret = 0;
02890 do
02891 {
02892 ret = _dbus_read (address_pipe[READ_END], address, 1024);
02893 }
02894 while (ret > 0);
02895
02896
02897 do
02898 {
02899 ret = waitpid (pid, &status, 0);
02900 }
02901 while (ret == -1 && errno == EINTR);
02902
02903
02904
02905 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
02906 _dbus_string_get_length (address) == orig_len)
02907 {
02908
02909 DBusString error_message;
02910 _dbus_string_init (&error_message);
02911 ret = 0;
02912 do
02913 {
02914 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
02915 }
02916 while (ret > 0);
02917
02918 _dbus_string_set_length (address, orig_len);
02919 if (_dbus_string_get_length (&error_message) > 0)
02920 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
02921 "dbus-launch failed to autolaunch D-Bus session: %s",
02922 _dbus_string_get_data (&error_message));
02923 else
02924 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
02925 "Failed to execute dbus-launch to autolaunch D-Bus session");
02926 goto out;
02927 }
02928
02929 retval = TRUE;
02930
02931 out:
02932 if (retval)
02933 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02934 else
02935 _DBUS_ASSERT_ERROR_IS_SET (error);
02936
02937 if (address_pipe[0] != -1)
02938 close (address_pipe[0]);
02939 if (address_pipe[1] != -1)
02940 close (address_pipe[1]);
02941 if (errors_pipe[0] != -1)
02942 close (errors_pipe[0]);
02943 if (errors_pipe[1] != -1)
02944 close (errors_pipe[1]);
02945
02946 _dbus_string_free (&uuid);
02947 return retval;
02948 }
02949
02968 dbus_bool_t
02969 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
02970 dbus_bool_t create_if_not_found,
02971 DBusError *error)
02972 {
02973 DBusString filename;
02974 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
02975 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
02976 }
02977
02978 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
02979 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
02980
02981
02999 dbus_bool_t
03000 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03001 {
03002 const char *xdg_data_home;
03003 const char *xdg_data_dirs;
03004 DBusString servicedir_path;
03005
03006 if (!_dbus_string_init (&servicedir_path))
03007 return FALSE;
03008
03009 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03010 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03011
03012 if (xdg_data_dirs != NULL)
03013 {
03014 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03015 goto oom;
03016
03017 if (!_dbus_string_append (&servicedir_path, ":"))
03018 goto oom;
03019 }
03020 else
03021 {
03022 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03023 goto oom;
03024 }
03025
03026
03027
03028
03029
03030
03031
03032 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03033 goto oom;
03034
03035 if (xdg_data_home != NULL)
03036 {
03037 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03038 goto oom;
03039 }
03040 else
03041 {
03042 const DBusString *homedir;
03043 DBusString local_share;
03044
03045 if (!_dbus_homedir_from_current_process (&homedir))
03046 goto oom;
03047
03048 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03049 goto oom;
03050
03051 _dbus_string_init_const (&local_share, "/.local/share");
03052 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03053 goto oom;
03054 }
03055
03056 if (!_dbus_split_paths_and_append (&servicedir_path,
03057 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03058 dirs))
03059 goto oom;
03060
03061 _dbus_string_free (&servicedir_path);
03062 return TRUE;
03063
03064 oom:
03065 _dbus_string_free (&servicedir_path);
03066 return FALSE;
03067 }
03068
03069
03088 dbus_bool_t
03089 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03090 {
03091 const char *xdg_data_dirs;
03092 DBusString servicedir_path;
03093
03094 if (!_dbus_string_init (&servicedir_path))
03095 return FALSE;
03096
03097 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03098
03099 if (xdg_data_dirs != NULL)
03100 {
03101 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03102 goto oom;
03103
03104 if (!_dbus_string_append (&servicedir_path, ":"))
03105 goto oom;
03106 }
03107 else
03108 {
03109 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03110 goto oom;
03111 }
03112
03113
03114
03115
03116
03117
03118
03119 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03120 goto oom;
03121
03122 if (!_dbus_split_paths_and_append (&servicedir_path,
03123 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03124 dirs))
03125 goto oom;
03126
03127 _dbus_string_free (&servicedir_path);
03128 return TRUE;
03129
03130 oom:
03131 _dbus_string_free (&servicedir_path);
03132 return FALSE;
03133 }
03134
03143 dbus_bool_t
03144 _dbus_append_system_config_file (DBusString *str)
03145 {
03146 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03147 }
03148
03155 dbus_bool_t
03156 _dbus_append_session_config_file (DBusString *str)
03157 {
03158 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03159 }
03160
03168 void
03169 _dbus_flush_caches (void)
03170 {
03171 _dbus_user_database_flush_system ();
03172 }
03173
03187 dbus_bool_t
03188 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03189 DBusCredentials *credentials)
03190 {
03191 DBusString homedir;
03192 DBusString dotdir;
03193 dbus_uid_t uid;
03194
03195 _dbus_assert (credentials != NULL);
03196 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03197
03198 if (!_dbus_string_init (&homedir))
03199 return FALSE;
03200
03201 uid = _dbus_credentials_get_unix_uid (credentials);
03202 _dbus_assert (uid != DBUS_UID_UNSET);
03203
03204 if (!_dbus_homedir_from_uid (uid, &homedir))
03205 goto failed;
03206
03207 #ifdef DBUS_BUILD_TESTS
03208 {
03209 const char *override;
03210
03211 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03212 if (override != NULL && *override != '\0')
03213 {
03214 _dbus_string_set_length (&homedir, 0);
03215 if (!_dbus_string_append (&homedir, override))
03216 goto failed;
03217
03218 _dbus_verbose ("Using fake homedir for testing: %s\n",
03219 _dbus_string_get_const_data (&homedir));
03220 }
03221 else
03222 {
03223 static dbus_bool_t already_warned = FALSE;
03224 if (!already_warned)
03225 {
03226 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03227 already_warned = TRUE;
03228 }
03229 }
03230 }
03231 #endif
03232
03233 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03234 if (!_dbus_concat_dir_and_file (&homedir,
03235 &dotdir))
03236 goto failed;
03237
03238 if (!_dbus_string_copy (&homedir, 0,
03239 directory, _dbus_string_get_length (directory))) {
03240 goto failed;
03241 }
03242
03243 _dbus_string_free (&homedir);
03244 return TRUE;
03245
03246 failed:
03247 _dbus_string_free (&homedir);
03248 return FALSE;
03249 }
03250
03251
03258 dbus_bool_t
03259 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03260 {
03261 return errno == EAGAIN || errno == EWOULDBLOCK;
03262 }
03263
03264