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