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 fprintf(stderr, "Family %s\n", family ? family : "none");
00783 hints.ai_protocol = IPPROTO_TCP;
00784 hints.ai_socktype = SOCK_STREAM;
00785 hints.ai_flags = AI_ADDRCONFIG;
00786
00787 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
00788 {
00789 dbus_set_error (error,
00790 _dbus_error_from_errno (errno),
00791 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
00792 host, port, gai_strerror(res), res);
00793 _dbus_close (fd, NULL);
00794 return -1;
00795 }
00796
00797 tmp = ai;
00798 while (tmp)
00799 {
00800 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
00801 {
00802 freeaddrinfo(ai);
00803 _DBUS_ASSERT_ERROR_IS_SET(error);
00804 return -1;
00805 }
00806 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00807
00808 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
00809 {
00810 _dbus_close(fd, NULL);
00811 fd = -1;
00812 tmp = tmp->ai_next;
00813 continue;
00814 }
00815
00816 break;
00817 }
00818 freeaddrinfo(ai);
00819
00820 if (fd == -1)
00821 {
00822 dbus_set_error (error,
00823 _dbus_error_from_errno (errno),
00824 "Failed to connect to socket \"%s:%s\" %s",
00825 host, port, _dbus_strerror(errno));
00826 return -1;
00827 }
00828
00829
00830 if (!_dbus_set_fd_nonblocking (fd, error))
00831 {
00832 _dbus_close (fd, NULL);
00833 fd = -1;
00834
00835 return -1;
00836 }
00837
00838 return fd;
00839 }
00840
00855 int
00856 _dbus_listen_tcp_socket (const char *host,
00857 const char *port,
00858 const char *family,
00859 DBusString *retport,
00860 int **fds_p,
00861 DBusError *error)
00862 {
00863 int nlisten_fd = 0, *listen_fd = NULL, res, i;
00864 struct addrinfo hints;
00865 struct addrinfo *ai, *tmp;
00866
00867 *fds_p = NULL;
00868 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00869
00870 _DBUS_ZERO (hints);
00871
00872 if (!family)
00873 hints.ai_family = AF_UNSPEC;
00874 else if (!strcmp(family, "ipv4"))
00875 hints.ai_family = AF_INET;
00876 else if (!strcmp(family, "ipv6"))
00877 hints.ai_family = AF_INET6;
00878 else
00879 {
00880 dbus_set_error (error,
00881 _dbus_error_from_errno (errno),
00882 "Unknown address family %s", family);
00883 return -1;
00884 }
00885
00886 hints.ai_protocol = IPPROTO_TCP;
00887 hints.ai_socktype = SOCK_STREAM;
00888 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
00889
00890 redo_lookup_with_port:
00891 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
00892 {
00893 dbus_set_error (error,
00894 _dbus_error_from_errno (errno),
00895 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
00896 host ? host : "*", port, gai_strerror(res), res);
00897 return -1;
00898 }
00899
00900 tmp = ai;
00901 while (tmp)
00902 {
00903 int fd = -1, *newlisten_fd;
00904 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
00905 {
00906 _DBUS_ASSERT_ERROR_IS_SET(error);
00907 goto failed;
00908 }
00909 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00910
00911 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
00912 {
00913 _dbus_close(fd, NULL);
00914 if (errno == EADDRINUSE)
00915 {
00916
00917
00918
00919 tmp = tmp->ai_next;
00920 continue;
00921 }
00922 dbus_set_error (error, _dbus_error_from_errno (errno),
00923 "Failed to bind socket \"%s:%s\": %s",
00924 host ? host : "*", port, _dbus_strerror (errno));
00925 goto failed;
00926 }
00927
00928 if (listen (fd, 30 ) < 0)
00929 {
00930 _dbus_close (fd, NULL);
00931 dbus_set_error (error, _dbus_error_from_errno (errno),
00932 "Failed to listen on socket \"%s:%s\": %s",
00933 host ? host : "*", port, _dbus_strerror (errno));
00934 goto failed;
00935 }
00936
00937 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
00938 if (!newlisten_fd)
00939 {
00940 _dbus_close (fd, NULL);
00941 dbus_set_error (error, _dbus_error_from_errno (errno),
00942 "Failed to allocate file handle array: %s",
00943 _dbus_strerror (errno));
00944 goto failed;
00945 }
00946 listen_fd = newlisten_fd;
00947 listen_fd[nlisten_fd] = fd;
00948 nlisten_fd++;
00949
00950 if (!_dbus_string_get_length(retport))
00951 {
00952
00953
00954
00955
00956 if (!port || !strcmp(port, "0"))
00957 {
00958 struct sockaddr_storage addr;
00959 socklen_t addrlen;
00960 char portbuf[50];
00961
00962 addrlen = sizeof(addr);
00963 getsockname(fd, (struct sockaddr*) &addr, &addrlen);
00964
00965 if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
00966 portbuf, sizeof(portbuf),
00967 NI_NUMERICHOST)) != 0)
00968 {
00969 dbus_set_error (error, _dbus_error_from_errno (errno),
00970 "Failed to resolve port \"%s:%s\": %s (%s)",
00971 host ? host : "*", port, gai_strerror(res), res);
00972 goto failed;
00973 }
00974 if (!_dbus_string_append(retport, portbuf))
00975 {
00976 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00977 goto failed;
00978 }
00979
00980
00981 port = _dbus_string_get_const_data(retport);
00982 freeaddrinfo(ai);
00983 goto redo_lookup_with_port;
00984 }
00985 else
00986 {
00987 if (!_dbus_string_append(retport, port))
00988 {
00989 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00990 goto failed;
00991 }
00992 }
00993 }
00994
00995 tmp = tmp->ai_next;
00996 }
00997 freeaddrinfo(ai);
00998 ai = NULL;
00999
01000 if (!nlisten_fd)
01001 {
01002 errno = EADDRINUSE;
01003 dbus_set_error (error, _dbus_error_from_errno (errno),
01004 "Failed to bind socket \"%s:%s\": %s",
01005 host ? host : "*", port, _dbus_strerror (errno));
01006 return -1;
01007 }
01008
01009 for (i = 0 ; i < nlisten_fd ; i++)
01010 {
01011 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01012 {
01013 goto failed;
01014 }
01015 }
01016
01017 *fds_p = listen_fd;
01018
01019 return nlisten_fd;
01020
01021 failed:
01022 if (ai)
01023 freeaddrinfo(ai);
01024 for (i = 0 ; i < nlisten_fd ; i++)
01025 _dbus_close(listen_fd[i], NULL);
01026 dbus_free(listen_fd);
01027 return -1;
01028 }
01029
01030 static dbus_bool_t
01031 write_credentials_byte (int server_fd,
01032 DBusError *error)
01033 {
01034 int bytes_written;
01035 char buf[1] = { '\0' };
01036 #if defined(HAVE_CMSGCRED)
01037 struct {
01038 struct cmsghdr hdr;
01039 struct cmsgcred cred;
01040 } cmsg;
01041 struct iovec iov;
01042 struct msghdr msg;
01043 iov.iov_base = buf;
01044 iov.iov_len = 1;
01045
01046 memset (&msg, 0, sizeof (msg));
01047 msg.msg_iov = &iov;
01048 msg.msg_iovlen = 1;
01049
01050 msg.msg_control = &cmsg;
01051 msg.msg_controllen = sizeof (cmsg);
01052 memset (&cmsg, 0, sizeof (cmsg));
01053 cmsg.hdr.cmsg_len = sizeof (cmsg);
01054 cmsg.hdr.cmsg_level = SOL_SOCKET;
01055 cmsg.hdr.cmsg_type = SCM_CREDS;
01056 #endif
01057
01058 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01059
01060 again:
01061
01062 #if defined(HAVE_CMSGCRED)
01063 bytes_written = sendmsg (server_fd, &msg, 0);
01064 #else
01065 bytes_written = write (server_fd, buf, 1);
01066 #endif
01067
01068 if (bytes_written < 0 && errno == EINTR)
01069 goto again;
01070
01071 if (bytes_written < 0)
01072 {
01073 dbus_set_error (error, _dbus_error_from_errno (errno),
01074 "Failed to write credentials byte: %s",
01075 _dbus_strerror (errno));
01076 return FALSE;
01077 }
01078 else if (bytes_written == 0)
01079 {
01080 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01081 "wrote zero bytes writing credentials byte");
01082 return FALSE;
01083 }
01084 else
01085 {
01086 _dbus_assert (bytes_written == 1);
01087 _dbus_verbose ("wrote credentials byte\n");
01088 return TRUE;
01089 }
01090 }
01091
01113 dbus_bool_t
01114 _dbus_read_credentials_socket (int client_fd,
01115 DBusCredentials *credentials,
01116 DBusError *error)
01117 {
01118 struct msghdr msg;
01119 struct iovec iov;
01120 char buf;
01121 dbus_uid_t uid_read;
01122 dbus_pid_t pid_read;
01123 int bytes_read;
01124
01125 uid_read = DBUS_UID_UNSET;
01126 pid_read = DBUS_PID_UNSET;
01127
01128 #ifdef HAVE_CMSGCRED
01129 struct {
01130 struct cmsghdr hdr;
01131 struct cmsgcred cred;
01132 } cmsg;
01133
01134 #elif defined(LOCAL_CREDS)
01135 struct {
01136 struct cmsghdr hdr;
01137 struct sockcred cred;
01138 } cmsg;
01139 #endif
01140
01141 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01142
01143
01144
01145
01146
01147 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01148 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01149 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01150
01151 _dbus_credentials_clear (credentials);
01152
01153
01154
01155
01156
01157
01158
01159 iov.iov_base = &buf;
01160 iov.iov_len = 1;
01161
01162 memset (&msg, 0, sizeof (msg));
01163 msg.msg_iov = &iov;
01164 msg.msg_iovlen = 1;
01165
01166 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01167 memset (&cmsg, 0, sizeof (cmsg));
01168 msg.msg_control = &cmsg;
01169 msg.msg_controllen = sizeof (cmsg);
01170 #endif
01171
01172 again:
01173 bytes_read = recvmsg (client_fd, &msg, 0);
01174
01175 if (bytes_read < 0)
01176 {
01177 if (errno == EINTR)
01178 goto again;
01179
01180
01181
01182
01183
01184
01185 dbus_set_error (error, _dbus_error_from_errno (errno),
01186 "Failed to read credentials byte: %s",
01187 _dbus_strerror (errno));
01188 return FALSE;
01189 }
01190 else if (bytes_read == 0)
01191 {
01192
01193
01194
01195 dbus_set_error (error, DBUS_ERROR_FAILED,
01196 "Failed to read credentials byte (zero-length read)");
01197 return FALSE;
01198 }
01199 else if (buf != '\0')
01200 {
01201 dbus_set_error (error, DBUS_ERROR_FAILED,
01202 "Credentials byte was not nul");
01203 return FALSE;
01204 }
01205
01206 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01207 if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
01208 {
01209 dbus_set_error (error, DBUS_ERROR_FAILED,
01210 "Message from recvmsg() was not SCM_CREDS");
01211 return FALSE;
01212 }
01213 #endif
01214
01215 _dbus_verbose ("read credentials byte\n");
01216
01217 {
01218 #ifdef SO_PEERCRED
01219 struct ucred cr;
01220 int cr_len = sizeof (cr);
01221
01222 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01223 cr_len == sizeof (cr))
01224 {
01225 pid_read = cr.pid;
01226 uid_read = cr.uid;
01227 }
01228 else
01229 {
01230 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01231 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01232 }
01233 #elif defined(HAVE_CMSGCRED)
01234 pid_read = cmsg.cred.cmcred_pid;
01235 uid_read = cmsg.cred.cmcred_euid;
01236 #elif defined(LOCAL_CREDS)
01237 pid_read = DBUS_PID_UNSET;
01238 uid_read = cmsg.cred.sc_uid;
01239
01240
01241 _dbus_set_local_creds (client_fd, FALSE);
01242 #elif defined(HAVE_GETPEEREID)
01243 uid_t euid;
01244 gid_t egid;
01245 if (getpeereid (client_fd, &euid, &egid) == 0)
01246 {
01247 uid_read = euid;
01248 }
01249 else
01250 {
01251 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01252 }
01253 #elif defined(HAVE_GETPEERUCRED)
01254 ucred_t * ucred = NULL;
01255 if (getpeerucred (client_fd, &ucred) == 0)
01256 {
01257 pid_read = ucred_getpid (ucred);
01258 uid_read = ucred_geteuid (ucred);
01259 }
01260 else
01261 {
01262 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01263 }
01264 if (ucred != NULL)
01265 ucred_free (ucred);
01266 #else
01267 _dbus_verbose ("Socket credentials not supported on this OS\n");
01268 #endif
01269 }
01270
01271 _dbus_verbose ("Credentials:"
01272 " pid "DBUS_PID_FORMAT
01273 " uid "DBUS_UID_FORMAT
01274 "\n",
01275 pid_read,
01276 uid_read);
01277
01278 if (pid_read != DBUS_PID_UNSET)
01279 {
01280 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01281 {
01282 _DBUS_SET_OOM (error);
01283 return FALSE;
01284 }
01285 }
01286
01287 if (uid_read != DBUS_UID_UNSET)
01288 {
01289 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01290 {
01291 _DBUS_SET_OOM (error);
01292 return FALSE;
01293 }
01294 }
01295
01296 return TRUE;
01297 }
01298
01316 dbus_bool_t
01317 _dbus_send_credentials_socket (int server_fd,
01318 DBusError *error)
01319 {
01320 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01321
01322 if (write_credentials_byte (server_fd, error))
01323 return TRUE;
01324 else
01325 return FALSE;
01326 }
01327
01335 int
01336 _dbus_accept (int listen_fd)
01337 {
01338 int client_fd;
01339 struct sockaddr addr;
01340 socklen_t addrlen;
01341
01342 addrlen = sizeof (addr);
01343
01344 retry:
01345 client_fd = accept (listen_fd, &addr, &addrlen);
01346
01347 if (client_fd < 0)
01348 {
01349 if (errno == EINTR)
01350 goto retry;
01351 }
01352
01353 _dbus_verbose ("client fd %d accepted\n", client_fd);
01354
01355 return client_fd;
01356 }
01357
01366 dbus_bool_t
01367 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01368 {
01369 const char *directory;
01370 struct stat sb;
01371
01372 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01373
01374 directory = _dbus_string_get_const_data (dir);
01375
01376 if (stat (directory, &sb) < 0)
01377 {
01378 dbus_set_error (error, _dbus_error_from_errno (errno),
01379 "%s", _dbus_strerror (errno));
01380
01381 return FALSE;
01382 }
01383
01384 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01385 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01386 {
01387 dbus_set_error (error, DBUS_ERROR_FAILED,
01388 "%s directory is not private to the user", directory);
01389 return FALSE;
01390 }
01391
01392 return TRUE;
01393 }
01394
01395 static dbus_bool_t
01396 fill_user_info_from_passwd (struct passwd *p,
01397 DBusUserInfo *info,
01398 DBusError *error)
01399 {
01400 _dbus_assert (p->pw_name != NULL);
01401 _dbus_assert (p->pw_dir != NULL);
01402
01403 info->uid = p->pw_uid;
01404 info->primary_gid = p->pw_gid;
01405 info->username = _dbus_strdup (p->pw_name);
01406 info->homedir = _dbus_strdup (p->pw_dir);
01407
01408 if (info->username == NULL ||
01409 info->homedir == NULL)
01410 {
01411 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01412 return FALSE;
01413 }
01414
01415 return TRUE;
01416 }
01417
01418 static dbus_bool_t
01419 fill_user_info (DBusUserInfo *info,
01420 dbus_uid_t uid,
01421 const DBusString *username,
01422 DBusError *error)
01423 {
01424 const char *username_c;
01425
01426
01427 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01428 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01429
01430 info->uid = DBUS_UID_UNSET;
01431 info->primary_gid = DBUS_GID_UNSET;
01432 info->group_ids = NULL;
01433 info->n_group_ids = 0;
01434 info->username = NULL;
01435 info->homedir = NULL;
01436
01437 if (username != NULL)
01438 username_c = _dbus_string_get_const_data (username);
01439 else
01440 username_c = NULL;
01441
01442
01443
01444
01445
01446
01447 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01448 {
01449 struct passwd *p;
01450 int result;
01451 char buf[1024];
01452 struct passwd p_str;
01453
01454 p = NULL;
01455 #ifdef HAVE_POSIX_GETPWNAM_R
01456 if (uid != DBUS_UID_UNSET)
01457 result = getpwuid_r (uid, &p_str, buf, sizeof (buf),
01458 &p);
01459 else
01460 result = getpwnam_r (username_c, &p_str, buf, sizeof (buf),
01461 &p);
01462 #else
01463 if (uid != DBUS_UID_UNSET)
01464 p = getpwuid_r (uid, &p_str, buf, sizeof (buf));
01465 else
01466 p = getpwnam_r (username_c, &p_str, buf, sizeof (buf));
01467 result = 0;
01468 #endif
01469 if (result == 0 && p == &p_str)
01470 {
01471 if (!fill_user_info_from_passwd (p, info, error))
01472 return FALSE;
01473 }
01474 else
01475 {
01476 dbus_set_error (error, _dbus_error_from_errno (errno),
01477 "User \"%s\" unknown or no memory to allocate password entry\n",
01478 username_c ? username_c : "???");
01479 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
01480 return FALSE;
01481 }
01482 }
01483 #else
01484 {
01485
01486 struct passwd *p;
01487
01488 if (uid != DBUS_UID_UNSET)
01489 p = getpwuid (uid);
01490 else
01491 p = getpwnam (username_c);
01492
01493 if (p != NULL)
01494 {
01495 if (!fill_user_info_from_passwd (p, info, error))
01496 return FALSE;
01497 }
01498 else
01499 {
01500 dbus_set_error (error, _dbus_error_from_errno (errno),
01501 "User \"%s\" unknown or no memory to allocate password entry\n",
01502 username_c ? username_c : "???");
01503 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
01504 return FALSE;
01505 }
01506 }
01507 #endif
01508
01509
01510 username_c = info->username;
01511
01512 #ifdef HAVE_GETGROUPLIST
01513 {
01514 gid_t *buf;
01515 int buf_count;
01516 int i;
01517
01518 buf_count = 17;
01519 buf = dbus_new (gid_t, buf_count);
01520 if (buf == NULL)
01521 {
01522 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01523 goto failed;
01524 }
01525
01526 if (getgrouplist (username_c,
01527 info->primary_gid,
01528 buf, &buf_count) < 0)
01529 {
01530 gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
01531 if (new == NULL)
01532 {
01533 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01534 dbus_free (buf);
01535 goto failed;
01536 }
01537
01538 buf = new;
01539
01540 errno = 0;
01541 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
01542 {
01543 dbus_set_error (error,
01544 _dbus_error_from_errno (errno),
01545 "Failed to get groups for username \"%s\" primary GID "
01546 DBUS_GID_FORMAT ": %s\n",
01547 username_c, info->primary_gid,
01548 _dbus_strerror (errno));
01549 dbus_free (buf);
01550 goto failed;
01551 }
01552 }
01553
01554 info->group_ids = dbus_new (dbus_gid_t, buf_count);
01555 if (info->group_ids == NULL)
01556 {
01557 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01558 dbus_free (buf);
01559 goto failed;
01560 }
01561
01562 for (i = 0; i < buf_count; ++i)
01563 info->group_ids[i] = buf[i];
01564
01565 info->n_group_ids = buf_count;
01566
01567 dbus_free (buf);
01568 }
01569 #else
01570 {
01571
01572 info->group_ids = dbus_new (dbus_gid_t, 1);
01573 if (info->group_ids == NULL)
01574 {
01575 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01576 goto failed;
01577 }
01578
01579 info->n_group_ids = 1;
01580
01581 (info->group_ids)[0] = info->primary_gid;
01582 }
01583 #endif
01584
01585 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01586
01587 return TRUE;
01588
01589 failed:
01590 _DBUS_ASSERT_ERROR_IS_SET (error);
01591 return FALSE;
01592 }
01593
01602 dbus_bool_t
01603 _dbus_user_info_fill (DBusUserInfo *info,
01604 const DBusString *username,
01605 DBusError *error)
01606 {
01607 return fill_user_info (info, DBUS_UID_UNSET,
01608 username, error);
01609 }
01610
01619 dbus_bool_t
01620 _dbus_user_info_fill_uid (DBusUserInfo *info,
01621 dbus_uid_t uid,
01622 DBusError *error)
01623 {
01624 return fill_user_info (info, uid,
01625 NULL, error);
01626 }
01627
01635 dbus_bool_t
01636 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
01637 {
01638
01639
01640
01641
01642 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01643 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01644 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01645
01646 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
01647 return FALSE;
01648 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
01649 return FALSE;
01650
01651 return TRUE;
01652 }
01653
01665 dbus_bool_t
01666 _dbus_append_user_from_current_process (DBusString *str)
01667 {
01668 return _dbus_string_append_uint (str,
01669 _dbus_geteuid ());
01670 }
01671
01676 dbus_pid_t
01677 _dbus_getpid (void)
01678 {
01679 return getpid ();
01680 }
01681
01685 dbus_uid_t
01686 _dbus_getuid (void)
01687 {
01688 return getuid ();
01689 }
01690
01694 dbus_uid_t
01695 _dbus_geteuid (void)
01696 {
01697 return geteuid ();
01698 }
01699
01706 unsigned long
01707 _dbus_pid_for_log (void)
01708 {
01709 return getpid ();
01710 }
01711
01719 dbus_bool_t
01720 _dbus_parse_uid (const DBusString *uid_str,
01721 dbus_uid_t *uid)
01722 {
01723 int end;
01724 long val;
01725
01726 if (_dbus_string_get_length (uid_str) == 0)
01727 {
01728 _dbus_verbose ("UID string was zero length\n");
01729 return FALSE;
01730 }
01731
01732 val = -1;
01733 end = 0;
01734 if (!_dbus_string_parse_int (uid_str, 0, &val,
01735 &end))
01736 {
01737 _dbus_verbose ("could not parse string as a UID\n");
01738 return FALSE;
01739 }
01740
01741 if (end != _dbus_string_get_length (uid_str))
01742 {
01743 _dbus_verbose ("string contained trailing stuff after UID\n");
01744 return FALSE;
01745 }
01746
01747 *uid = val;
01748
01749 return TRUE;
01750 }
01751
01752
01753 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
01754
01755 #if DBUS_USE_ATOMIC_INT_486_COND
01756
01757
01758 static inline dbus_int32_t
01759 atomic_exchange_and_add (DBusAtomic *atomic,
01760 volatile dbus_int32_t val)
01761 {
01762 register dbus_int32_t result;
01763
01764 __asm__ __volatile__ ("lock; xaddl %0,%1"
01765 : "=r" (result), "=m" (atomic->value)
01766 : "0" (val), "m" (atomic->value));
01767 return result;
01768 }
01769 #endif
01770
01779 dbus_int32_t
01780 _dbus_atomic_inc (DBusAtomic *atomic)
01781 {
01782 #if DBUS_USE_ATOMIC_INT_486_COND
01783 return atomic_exchange_and_add (atomic, 1);
01784 #else
01785 dbus_int32_t res;
01786 _DBUS_LOCK (atomic);
01787 res = atomic->value;
01788 atomic->value += 1;
01789 _DBUS_UNLOCK (atomic);
01790 return res;
01791 #endif
01792 }
01793
01802 dbus_int32_t
01803 _dbus_atomic_dec (DBusAtomic *atomic)
01804 {
01805 #if DBUS_USE_ATOMIC_INT_486_COND
01806 return atomic_exchange_and_add (atomic, -1);
01807 #else
01808 dbus_int32_t res;
01809
01810 _DBUS_LOCK (atomic);
01811 res = atomic->value;
01812 atomic->value -= 1;
01813 _DBUS_UNLOCK (atomic);
01814 return res;
01815 #endif
01816 }
01817
01818 #ifdef DBUS_BUILD_TESTS
01819
01822 dbus_gid_t
01823 _dbus_getgid (void)
01824 {
01825 return getgid ();
01826 }
01827 #endif
01828
01837 int
01838 _dbus_poll (DBusPollFD *fds,
01839 int n_fds,
01840 int timeout_milliseconds)
01841 {
01842 #ifdef HAVE_POLL
01843
01844
01845
01846
01847 if (_DBUS_POLLIN == POLLIN &&
01848 _DBUS_POLLPRI == POLLPRI &&
01849 _DBUS_POLLOUT == POLLOUT &&
01850 _DBUS_POLLERR == POLLERR &&
01851 _DBUS_POLLHUP == POLLHUP &&
01852 _DBUS_POLLNVAL == POLLNVAL &&
01853 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
01854 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
01855 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
01856 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
01857 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
01858 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
01859 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
01860 {
01861 return poll ((struct pollfd*) fds,
01862 n_fds,
01863 timeout_milliseconds);
01864 }
01865 else
01866 {
01867
01868
01869
01870 _dbus_warn ("didn't implement poll() properly for this system yet\n");
01871 return -1;
01872 }
01873 #else
01874
01875 fd_set read_set, write_set, err_set;
01876 int max_fd = 0;
01877 int i;
01878 struct timeval tv;
01879 int ready;
01880
01881 FD_ZERO (&read_set);
01882 FD_ZERO (&write_set);
01883 FD_ZERO (&err_set);
01884
01885 for (i = 0; i < n_fds; i++)
01886 {
01887 DBusPollFD *fdp = &fds[i];
01888
01889 if (fdp->events & _DBUS_POLLIN)
01890 FD_SET (fdp->fd, &read_set);
01891
01892 if (fdp->events & _DBUS_POLLOUT)
01893 FD_SET (fdp->fd, &write_set);
01894
01895 FD_SET (fdp->fd, &err_set);
01896
01897 max_fd = MAX (max_fd, fdp->fd);
01898 }
01899
01900 tv.tv_sec = timeout_milliseconds / 1000;
01901 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
01902
01903 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
01904 timeout_milliseconds < 0 ? NULL : &tv);
01905
01906 if (ready > 0)
01907 {
01908 for (i = 0; i < n_fds; i++)
01909 {
01910 DBusPollFD *fdp = &fds[i];
01911
01912 fdp->revents = 0;
01913
01914 if (FD_ISSET (fdp->fd, &read_set))
01915 fdp->revents |= _DBUS_POLLIN;
01916
01917 if (FD_ISSET (fdp->fd, &write_set))
01918 fdp->revents |= _DBUS_POLLOUT;
01919
01920 if (FD_ISSET (fdp->fd, &err_set))
01921 fdp->revents |= _DBUS_POLLERR;
01922 }
01923 }
01924
01925 return ready;
01926 #endif
01927 }
01928
01935 void
01936 _dbus_get_current_time (long *tv_sec,
01937 long *tv_usec)
01938 {
01939 struct timeval t;
01940
01941 gettimeofday (&t, NULL);
01942
01943 if (tv_sec)
01944 *tv_sec = t.tv_sec;
01945 if (tv_usec)
01946 *tv_usec = t.tv_usec;
01947 }
01948
01959 dbus_bool_t
01960 _dbus_file_get_contents (DBusString *str,
01961 const DBusString *filename,
01962 DBusError *error)
01963 {
01964 int fd;
01965 struct stat sb;
01966 int orig_len;
01967 int total;
01968 const char *filename_c;
01969
01970 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01971
01972 filename_c = _dbus_string_get_const_data (filename);
01973
01974
01975 fd = open (filename_c, O_RDONLY | O_BINARY);
01976 if (fd < 0)
01977 {
01978 dbus_set_error (error, _dbus_error_from_errno (errno),
01979 "Failed to open \"%s\": %s",
01980 filename_c,
01981 _dbus_strerror (errno));
01982 return FALSE;
01983 }
01984
01985 _dbus_verbose ("file fd %d opened\n", fd);
01986
01987 if (fstat (fd, &sb) < 0)
01988 {
01989 dbus_set_error (error, _dbus_error_from_errno (errno),
01990 "Failed to stat \"%s\": %s",
01991 filename_c,
01992 _dbus_strerror (errno));
01993
01994 _dbus_verbose ("fstat() failed: %s",
01995 _dbus_strerror (errno));
01996
01997 _dbus_close (fd, NULL);
01998
01999 return FALSE;
02000 }
02001
02002 if (sb.st_size > _DBUS_ONE_MEGABYTE)
02003 {
02004 dbus_set_error (error, DBUS_ERROR_FAILED,
02005 "File size %lu of \"%s\" is too large.",
02006 (unsigned long) sb.st_size, filename_c);
02007 _dbus_close (fd, NULL);
02008 return FALSE;
02009 }
02010
02011 total = 0;
02012 orig_len = _dbus_string_get_length (str);
02013 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
02014 {
02015 int bytes_read;
02016
02017 while (total < (int) sb.st_size)
02018 {
02019 bytes_read = _dbus_read (fd, str,
02020 sb.st_size - total);
02021 if (bytes_read <= 0)
02022 {
02023 dbus_set_error (error, _dbus_error_from_errno (errno),
02024 "Error reading \"%s\": %s",
02025 filename_c,
02026 _dbus_strerror (errno));
02027
02028 _dbus_verbose ("read() failed: %s",
02029 _dbus_strerror (errno));
02030
02031 _dbus_close (fd, NULL);
02032 _dbus_string_set_length (str, orig_len);
02033 return FALSE;
02034 }
02035 else
02036 total += bytes_read;
02037 }
02038
02039 _dbus_close (fd, NULL);
02040 return TRUE;
02041 }
02042 else if (sb.st_size != 0)
02043 {
02044 _dbus_verbose ("Can only open regular files at the moment.\n");
02045 dbus_set_error (error, DBUS_ERROR_FAILED,
02046 "\"%s\" is not a regular file",
02047 filename_c);
02048 _dbus_close (fd, NULL);
02049 return FALSE;
02050 }
02051 else
02052 {
02053 _dbus_close (fd, NULL);
02054 return TRUE;
02055 }
02056 }
02057
02067 dbus_bool_t
02068 _dbus_string_save_to_file (const DBusString *str,
02069 const DBusString *filename,
02070 DBusError *error)
02071 {
02072 int fd;
02073 int bytes_to_write;
02074 const char *filename_c;
02075 DBusString tmp_filename;
02076 const char *tmp_filename_c;
02077 int total;
02078 dbus_bool_t need_unlink;
02079 dbus_bool_t retval;
02080
02081 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02082
02083 fd = -1;
02084 retval = FALSE;
02085 need_unlink = FALSE;
02086
02087 if (!_dbus_string_init (&tmp_filename))
02088 {
02089 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02090 return FALSE;
02091 }
02092
02093 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
02094 {
02095 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02096 _dbus_string_free (&tmp_filename);
02097 return FALSE;
02098 }
02099
02100 if (!_dbus_string_append (&tmp_filename, "."))
02101 {
02102 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02103 _dbus_string_free (&tmp_filename);
02104 return FALSE;
02105 }
02106
02107 #define N_TMP_FILENAME_RANDOM_BYTES 8
02108 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
02109 {
02110 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02111 _dbus_string_free (&tmp_filename);
02112 return FALSE;
02113 }
02114
02115 filename_c = _dbus_string_get_const_data (filename);
02116 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
02117
02118 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
02119 0600);
02120 if (fd < 0)
02121 {
02122 dbus_set_error (error, _dbus_error_from_errno (errno),
02123 "Could not create %s: %s", tmp_filename_c,
02124 _dbus_strerror (errno));
02125 goto out;
02126 }
02127
02128 _dbus_verbose ("tmp file fd %d opened\n", fd);
02129
02130 need_unlink = TRUE;
02131
02132 total = 0;
02133 bytes_to_write = _dbus_string_get_length (str);
02134
02135 while (total < bytes_to_write)
02136 {
02137 int bytes_written;
02138
02139 bytes_written = _dbus_write (fd, str, total,
02140 bytes_to_write - total);
02141
02142 if (bytes_written <= 0)
02143 {
02144 dbus_set_error (error, _dbus_error_from_errno (errno),
02145 "Could not write to %s: %s", tmp_filename_c,
02146 _dbus_strerror (errno));
02147
02148 goto out;
02149 }
02150
02151 total += bytes_written;
02152 }
02153
02154 if (!_dbus_close (fd, NULL))
02155 {
02156 dbus_set_error (error, _dbus_error_from_errno (errno),
02157 "Could not close file %s: %s",
02158 tmp_filename_c, _dbus_strerror (errno));
02159
02160 goto out;
02161 }
02162
02163 fd = -1;
02164
02165 if (rename (tmp_filename_c, filename_c) < 0)
02166 {
02167 dbus_set_error (error, _dbus_error_from_errno (errno),
02168 "Could not rename %s to %s: %s",
02169 tmp_filename_c, filename_c,
02170 _dbus_strerror (errno));
02171
02172 goto out;
02173 }
02174
02175 need_unlink = FALSE;
02176
02177 retval = TRUE;
02178
02179 out:
02180
02181
02182
02183
02184 if (fd >= 0)
02185 _dbus_close (fd, NULL);
02186
02187 if (need_unlink && unlink (tmp_filename_c) < 0)
02188 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
02189 tmp_filename_c, _dbus_strerror (errno));
02190
02191 _dbus_string_free (&tmp_filename);
02192
02193 if (!retval)
02194 _DBUS_ASSERT_ERROR_IS_SET (error);
02195
02196 return retval;
02197 }
02198
02205 dbus_bool_t
02206 _dbus_make_file_world_readable(const DBusString *filename,
02207 DBusError *error)
02208 {
02209 const char *filename_c;
02210
02211 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02212
02213 filename_c = _dbus_string_get_const_data (filename);
02214 if (chmod (filename_c, 0644) == -1)
02215 {
02216 dbus_set_error (error,
02217 DBUS_ERROR_FAILED,
02218 "Could not change permissions of file %s: %s\n",
02219 filename_c,
02220 _dbus_strerror (errno));
02221 return FALSE;
02222 }
02223 return TRUE;
02224 }
02225
02232 dbus_bool_t
02233 _dbus_create_file_exclusively (const DBusString *filename,
02234 DBusError *error)
02235 {
02236 int fd;
02237 const char *filename_c;
02238
02239 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02240
02241 filename_c = _dbus_string_get_const_data (filename);
02242
02243 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
02244 0600);
02245 if (fd < 0)
02246 {
02247 dbus_set_error (error,
02248 DBUS_ERROR_FAILED,
02249 "Could not create file %s: %s\n",
02250 filename_c,
02251 _dbus_strerror (errno));
02252 return FALSE;
02253 }
02254
02255 _dbus_verbose ("exclusive file fd %d opened\n", fd);
02256
02257 if (!_dbus_close (fd, NULL))
02258 {
02259 dbus_set_error (error,
02260 DBUS_ERROR_FAILED,
02261 "Could not close file %s: %s\n",
02262 filename_c,
02263 _dbus_strerror (errno));
02264 return FALSE;
02265 }
02266
02267 return TRUE;
02268 }
02269
02278 dbus_bool_t
02279 _dbus_delete_file (const DBusString *filename,
02280 DBusError *error)
02281 {
02282 const char *filename_c;
02283
02284 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02285
02286 filename_c = _dbus_string_get_const_data (filename);
02287
02288 if (unlink (filename_c) < 0)
02289 {
02290 dbus_set_error (error, DBUS_ERROR_FAILED,
02291 "Failed to delete file %s: %s\n",
02292 filename_c, _dbus_strerror (errno));
02293 return FALSE;
02294 }
02295 else
02296 return TRUE;
02297 }
02298
02307 dbus_bool_t
02308 _dbus_create_directory (const DBusString *filename,
02309 DBusError *error)
02310 {
02311 const char *filename_c;
02312
02313 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02314
02315 filename_c = _dbus_string_get_const_data (filename);
02316
02317 if (mkdir (filename_c, 0700) < 0)
02318 {
02319 if (errno == EEXIST)
02320 return TRUE;
02321
02322 dbus_set_error (error, DBUS_ERROR_FAILED,
02323 "Failed to create directory %s: %s\n",
02324 filename_c, _dbus_strerror (errno));
02325 return FALSE;
02326 }
02327 else
02328 return TRUE;
02329 }
02330
02341 dbus_bool_t
02342 _dbus_concat_dir_and_file (DBusString *dir,
02343 const DBusString *next_component)
02344 {
02345 dbus_bool_t dir_ends_in_slash;
02346 dbus_bool_t file_starts_with_slash;
02347
02348 if (_dbus_string_get_length (dir) == 0 ||
02349 _dbus_string_get_length (next_component) == 0)
02350 return TRUE;
02351
02352 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02353 _dbus_string_get_length (dir) - 1);
02354
02355 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02356
02357 if (dir_ends_in_slash && file_starts_with_slash)
02358 {
02359 _dbus_string_shorten (dir, 1);
02360 }
02361 else if (!(dir_ends_in_slash || file_starts_with_slash))
02362 {
02363 if (!_dbus_string_append_byte (dir, '/'))
02364 return FALSE;
02365 }
02366
02367 return _dbus_string_copy (next_component, 0, dir,
02368 _dbus_string_get_length (dir));
02369 }
02370
02372 #define NANOSECONDS_PER_SECOND 1000000000
02373
02374 #define MICROSECONDS_PER_SECOND 1000000
02375
02376 #define MILLISECONDS_PER_SECOND 1000
02377
02378 #define NANOSECONDS_PER_MILLISECOND 1000000
02379
02380 #define MICROSECONDS_PER_MILLISECOND 1000
02381
02386 void
02387 _dbus_sleep_milliseconds (int milliseconds)
02388 {
02389 #ifdef HAVE_NANOSLEEP
02390 struct timespec req;
02391 struct timespec rem;
02392
02393 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02394 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02395 rem.tv_sec = 0;
02396 rem.tv_nsec = 0;
02397
02398 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02399 req = rem;
02400 #elif defined (HAVE_USLEEP)
02401 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02402 #else
02403 sleep (MAX (milliseconds / 1000, 1));
02404 #endif
02405 }
02406
02407 static dbus_bool_t
02408 _dbus_generate_pseudorandom_bytes (DBusString *str,
02409 int n_bytes)
02410 {
02411 int old_len;
02412 char *p;
02413
02414 old_len = _dbus_string_get_length (str);
02415
02416 if (!_dbus_string_lengthen (str, n_bytes))
02417 return FALSE;
02418
02419 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02420
02421 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02422
02423 return TRUE;
02424 }
02425
02434 dbus_bool_t
02435 _dbus_generate_random_bytes (DBusString *str,
02436 int n_bytes)
02437 {
02438 int old_len;
02439 int fd;
02440
02441
02442
02443
02444
02445
02446
02447 old_len = _dbus_string_get_length (str);
02448 fd = -1;
02449
02450
02451 fd = open ("/dev/urandom", O_RDONLY);
02452 if (fd < 0)
02453 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02454
02455 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02456
02457 if (_dbus_read (fd, str, n_bytes) != n_bytes)
02458 {
02459 _dbus_close (fd, NULL);
02460 _dbus_string_set_length (str, old_len);
02461 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02462 }
02463
02464 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02465 n_bytes);
02466
02467 _dbus_close (fd, NULL);
02468
02469 return TRUE;
02470 }
02471
02477 void
02478 _dbus_exit (int code)
02479 {
02480 _exit (code);
02481 }
02482
02491 const char*
02492 _dbus_strerror (int error_number)
02493 {
02494 const char *msg;
02495
02496 msg = strerror (error_number);
02497 if (msg == NULL)
02498 msg = "unknown";
02499
02500 return msg;
02501 }
02502
02506 void
02507 _dbus_disable_sigpipe (void)
02508 {
02509 signal (SIGPIPE, SIG_IGN);
02510 }
02511
02519 void
02520 _dbus_fd_set_close_on_exec (int fd)
02521 {
02522 int val;
02523
02524 val = fcntl (fd, F_GETFD, 0);
02525
02526 if (val < 0)
02527 return;
02528
02529 val |= FD_CLOEXEC;
02530
02531 fcntl (fd, F_SETFD, val);
02532 }
02533
02541 dbus_bool_t
02542 _dbus_close (int fd,
02543 DBusError *error)
02544 {
02545 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02546
02547 again:
02548 if (close (fd) < 0)
02549 {
02550 if (errno == EINTR)
02551 goto again;
02552
02553 dbus_set_error (error, _dbus_error_from_errno (errno),
02554 "Could not close fd %d", fd);
02555 return FALSE;
02556 }
02557
02558 return TRUE;
02559 }
02560
02568 dbus_bool_t
02569 _dbus_set_fd_nonblocking (int fd,
02570 DBusError *error)
02571 {
02572 int val;
02573
02574 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02575
02576 val = fcntl (fd, F_GETFL, 0);
02577 if (val < 0)
02578 {
02579 dbus_set_error (error, _dbus_error_from_errno (errno),
02580 "Failed to get flags from file descriptor %d: %s",
02581 fd, _dbus_strerror (errno));
02582 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02583 _dbus_strerror (errno));
02584 return FALSE;
02585 }
02586
02587 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02588 {
02589 dbus_set_error (error, _dbus_error_from_errno (errno),
02590 "Failed to set nonblocking flag of file descriptor %d: %s",
02591 fd, _dbus_strerror (errno));
02592 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02593 fd, _dbus_strerror (errno));
02594
02595 return FALSE;
02596 }
02597
02598 return TRUE;
02599 }
02600
02606 void
02607 _dbus_print_backtrace (void)
02608 {
02609 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02610 void *bt[500];
02611 int bt_size;
02612 int i;
02613 char **syms;
02614
02615 bt_size = backtrace (bt, 500);
02616
02617 syms = backtrace_symbols (bt, bt_size);
02618
02619 i = 0;
02620 while (i < bt_size)
02621 {
02622
02623 fprintf (stderr, " %s\n", syms[i]);
02624 ++i;
02625 }
02626 fflush (stderr);
02627
02628 free (syms);
02629 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02630 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
02631 #else
02632 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02633 #endif
02634 }
02635
02651 dbus_bool_t
02652 _dbus_full_duplex_pipe (int *fd1,
02653 int *fd2,
02654 dbus_bool_t blocking,
02655 DBusError *error)
02656 {
02657 #ifdef HAVE_SOCKETPAIR
02658 int fds[2];
02659
02660 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02661
02662 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
02663 {
02664 dbus_set_error (error, _dbus_error_from_errno (errno),
02665 "Could not create full-duplex pipe");
02666 return FALSE;
02667 }
02668
02669 if (!blocking &&
02670 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02671 !_dbus_set_fd_nonblocking (fds[1], NULL)))
02672 {
02673 dbus_set_error (error, _dbus_error_from_errno (errno),
02674 "Could not set full-duplex pipe nonblocking");
02675
02676 _dbus_close (fds[0], NULL);
02677 _dbus_close (fds[1], NULL);
02678
02679 return FALSE;
02680 }
02681
02682 *fd1 = fds[0];
02683 *fd2 = fds[1];
02684
02685 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02686 *fd1, *fd2);
02687
02688 return TRUE;
02689 #else
02690 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
02691 dbus_set_error (error, DBUS_ERROR_FAILED,
02692 "_dbus_full_duplex_pipe() not implemented on this OS");
02693 return FALSE;
02694 #endif
02695 }
02696
02697
02706 int
02707 _dbus_printf_string_upper_bound (const char *format,
02708 va_list args)
02709 {
02710 char c;
02711 return vsnprintf (&c, 1, format, args);
02712 }
02713
02720 const char*
02721 _dbus_get_tmpdir(void)
02722 {
02723 static const char* tmpdir = NULL;
02724
02725 if (tmpdir == NULL)
02726 {
02727
02728
02729
02730
02731 if (tmpdir == NULL)
02732 tmpdir = getenv("TMPDIR");
02733
02734
02735
02736
02737 if (tmpdir == NULL)
02738 tmpdir = getenv("TMP");
02739 if (tmpdir == NULL)
02740 tmpdir = getenv("TEMP");
02741
02742
02743 if (tmpdir == NULL)
02744 tmpdir = "/tmp";
02745 }
02746
02747 _dbus_assert(tmpdir != NULL);
02748
02749 return tmpdir;
02750 }
02751
02764 dbus_bool_t
02765 _dbus_get_autolaunch_address (DBusString *address,
02766 DBusError *error)
02767 {
02768 static char *argv[6];
02769 int address_pipe[2] = { -1, -1 };
02770 int errors_pipe[2] = { -1, -1 };
02771 pid_t pid;
02772 int ret;
02773 int status;
02774 int orig_len;
02775 int i;
02776 DBusString uuid;
02777 dbus_bool_t retval;
02778
02779 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02780 retval = FALSE;
02781
02782 if (!_dbus_string_init (&uuid))
02783 {
02784 _DBUS_SET_OOM (error);
02785 return FALSE;
02786 }
02787
02788 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
02789 {
02790 _DBUS_SET_OOM (error);
02791 goto out;
02792 }
02793
02794 i = 0;
02795 argv[i] = "dbus-launch";
02796 ++i;
02797 argv[i] = "--autolaunch";
02798 ++i;
02799 argv[i] = _dbus_string_get_data (&uuid);
02800 ++i;
02801 argv[i] = "--binary-syntax";
02802 ++i;
02803 argv[i] = "--close-stderr";
02804 ++i;
02805 argv[i] = NULL;
02806 ++i;
02807
02808 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
02809
02810 orig_len = _dbus_string_get_length (address);
02811
02812 #define READ_END 0
02813 #define WRITE_END 1
02814 if (pipe (address_pipe) < 0)
02815 {
02816 dbus_set_error (error, _dbus_error_from_errno (errno),
02817 "Failed to create a pipe: %s",
02818 _dbus_strerror (errno));
02819 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
02820 _dbus_strerror (errno));
02821 goto out;
02822 }
02823 if (pipe (errors_pipe) < 0)
02824 {
02825 dbus_set_error (error, _dbus_error_from_errno (errno),
02826 "Failed to create a pipe: %s",
02827 _dbus_strerror (errno));
02828 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
02829 _dbus_strerror (errno));
02830 goto out;
02831 }
02832
02833 pid = fork ();
02834 if (pid < 0)
02835 {
02836 dbus_set_error (error, _dbus_error_from_errno (errno),
02837 "Failed to fork(): %s",
02838 _dbus_strerror (errno));
02839 _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
02840 _dbus_strerror (errno));
02841 goto out;
02842 }
02843
02844 if (pid == 0)
02845 {
02846
02847 int fd = open ("/dev/null", O_RDWR);
02848 if (fd == -1)
02849
02850 _exit (1);
02851
02852 _dbus_verbose ("/dev/null fd %d opened\n", fd);
02853
02854
02855 close (address_pipe[READ_END]);
02856 close (errors_pipe[READ_END]);
02857 close (0);
02858 close (1);
02859 close (2);
02860
02861 if (dup2 (fd, 0) == -1)
02862 _exit (1);
02863 if (dup2 (address_pipe[WRITE_END], 1) == -1)
02864 _exit (1);
02865 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
02866 _exit (1);
02867
02868 close (fd);
02869 close (address_pipe[WRITE_END]);
02870 close (errors_pipe[WRITE_END]);
02871
02872 execv (DBUS_BINDIR "/dbus-launch", argv);
02873
02874
02875 execvp ("dbus-launch", argv);
02876
02877
02878 _exit (1);
02879 }
02880
02881
02882 close (address_pipe[WRITE_END]);
02883 close (errors_pipe[WRITE_END]);
02884 address_pipe[WRITE_END] = -1;
02885 errors_pipe[WRITE_END] = -1;
02886
02887 ret = 0;
02888 do
02889 {
02890 ret = _dbus_read (address_pipe[READ_END], address, 1024);
02891 }
02892 while (ret > 0);
02893
02894
02895 do
02896 {
02897 ret = waitpid (pid, &status, 0);
02898 }
02899 while (ret == -1 && errno == EINTR);
02900
02901
02902
02903 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
02904 _dbus_string_get_length (address) == orig_len)
02905 {
02906
02907 DBusString error_message;
02908 _dbus_string_init (&error_message);
02909 ret = 0;
02910 do
02911 {
02912 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
02913 }
02914 while (ret > 0);
02915
02916 _dbus_string_set_length (address, orig_len);
02917 if (_dbus_string_get_length (&error_message) > 0)
02918 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
02919 "dbus-launch failed to autolaunch D-Bus session: %s",
02920 _dbus_string_get_data (&error_message));
02921 else
02922 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
02923 "Failed to execute dbus-launch to autolaunch D-Bus session");
02924 goto out;
02925 }
02926
02927 retval = TRUE;
02928
02929 out:
02930 if (retval)
02931 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02932 else
02933 _DBUS_ASSERT_ERROR_IS_SET (error);
02934
02935 if (address_pipe[0] != -1)
02936 close (address_pipe[0]);
02937 if (address_pipe[1] != -1)
02938 close (address_pipe[1]);
02939 if (errors_pipe[0] != -1)
02940 close (errors_pipe[0]);
02941 if (errors_pipe[1] != -1)
02942 close (errors_pipe[1]);
02943
02944 _dbus_string_free (&uuid);
02945 return retval;
02946 }
02947
02966 dbus_bool_t
02967 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
02968 dbus_bool_t create_if_not_found,
02969 DBusError *error)
02970 {
02971 DBusString filename;
02972 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
02973 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
02974 }
02975
02976 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
02977 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
02978
02979
02997 dbus_bool_t
02998 _dbus_get_standard_session_servicedirs (DBusList **dirs)
02999 {
03000 const char *xdg_data_home;
03001 const char *xdg_data_dirs;
03002 DBusString servicedir_path;
03003
03004 if (!_dbus_string_init (&servicedir_path))
03005 return FALSE;
03006
03007 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03008 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03009
03010 if (xdg_data_dirs != NULL)
03011 {
03012 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03013 goto oom;
03014
03015 if (!_dbus_string_append (&servicedir_path, ":"))
03016 goto oom;
03017 }
03018 else
03019 {
03020 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03021 goto oom;
03022 }
03023
03024
03025
03026
03027
03028
03029
03030 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03031 goto oom;
03032
03033 if (xdg_data_home != NULL)
03034 {
03035 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03036 goto oom;
03037 }
03038 else
03039 {
03040 const DBusString *homedir;
03041 DBusString local_share;
03042
03043 if (!_dbus_homedir_from_current_process (&homedir))
03044 goto oom;
03045
03046 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03047 goto oom;
03048
03049 _dbus_string_init_const (&local_share, "/.local/share");
03050 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03051 goto oom;
03052 }
03053
03054 if (!_dbus_split_paths_and_append (&servicedir_path,
03055 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03056 dirs))
03057 goto oom;
03058
03059 _dbus_string_free (&servicedir_path);
03060 return TRUE;
03061
03062 oom:
03063 _dbus_string_free (&servicedir_path);
03064 return FALSE;
03065 }
03066
03067
03086 dbus_bool_t
03087 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03088 {
03089 const char *xdg_data_dirs;
03090 DBusString servicedir_path;
03091
03092 if (!_dbus_string_init (&servicedir_path))
03093 return FALSE;
03094
03095 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03096
03097 if (xdg_data_dirs != NULL)
03098 {
03099 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03100 goto oom;
03101
03102 if (!_dbus_string_append (&servicedir_path, ":"))
03103 goto oom;
03104 }
03105 else
03106 {
03107 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03108 goto oom;
03109 }
03110
03111
03112
03113
03114
03115
03116
03117 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03118 goto oom;
03119
03120 if (!_dbus_split_paths_and_append (&servicedir_path,
03121 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03122 dirs))
03123 goto oom;
03124
03125 _dbus_string_free (&servicedir_path);
03126 return TRUE;
03127
03128 oom:
03129 _dbus_string_free (&servicedir_path);
03130 return FALSE;
03131 }
03132
03141 dbus_bool_t
03142 _dbus_append_system_config_file (DBusString *str)
03143 {
03144 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03145 }
03146
03153 dbus_bool_t
03154 _dbus_append_session_config_file (DBusString *str)
03155 {
03156 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03157 }
03158
03166 void
03167 _dbus_flush_caches (void)
03168 {
03169 _dbus_user_database_flush_system ();
03170 }
03171
03185 dbus_bool_t
03186 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03187 DBusCredentials *credentials)
03188 {
03189 DBusString homedir;
03190 DBusString dotdir;
03191 dbus_uid_t uid;
03192
03193 _dbus_assert (credentials != NULL);
03194 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03195
03196 if (!_dbus_string_init (&homedir))
03197 return FALSE;
03198
03199 uid = _dbus_credentials_get_unix_uid (credentials);
03200 _dbus_assert (uid != DBUS_UID_UNSET);
03201
03202 if (!_dbus_homedir_from_uid (uid, &homedir))
03203 goto failed;
03204
03205 #ifdef DBUS_BUILD_TESTS
03206 {
03207 const char *override;
03208
03209 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03210 if (override != NULL && *override != '\0')
03211 {
03212 _dbus_string_set_length (&homedir, 0);
03213 if (!_dbus_string_append (&homedir, override))
03214 goto failed;
03215
03216 _dbus_verbose ("Using fake homedir for testing: %s\n",
03217 _dbus_string_get_const_data (&homedir));
03218 }
03219 else
03220 {
03221 static dbus_bool_t already_warned = FALSE;
03222 if (!already_warned)
03223 {
03224 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03225 already_warned = TRUE;
03226 }
03227 }
03228 }
03229 #endif
03230
03231 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03232 if (!_dbus_concat_dir_and_file (&homedir,
03233 &dotdir))
03234 goto failed;
03235
03236 if (!_dbus_string_copy (&homedir, 0,
03237 directory, _dbus_string_get_length (directory))) {
03238 goto failed;
03239 }
03240
03241 _dbus_string_free (&homedir);
03242 return TRUE;
03243
03244 failed:
03245 _dbus_string_free (&homedir);
03246 return FALSE;
03247 }
03248
03249
03256 dbus_bool_t
03257 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03258 {
03259 return errno == EAGAIN || errno == EWOULDBLOCK;
03260 }
03261
03262