int fd;
size_t path_len;
struct sockaddr_un addr;
+ _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
if (abstract)
{
-#ifdef HAVE_ABSTRACT_SOCKETS
+#ifdef __linux__
addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
path_len++; /* Account for the extra nul byte added to the start of sun_path */
return -1;
}
- strncpy (&addr.sun_path[1], path, path_len);
+ strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
/* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
-#else /* HAVE_ABSTRACT_SOCKETS */
+#else /* !__linux__ */
dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
"Operating system does not support abstract socket namespace\n");
_dbus_close (fd, NULL);
return -1;
-#endif /* ! HAVE_ABSTRACT_SOCKETS */
+#endif /* !__linux__ */
}
else
{
return -1;
}
- strncpy (addr.sun_path, path, path_len);
+ strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
}
if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
int listen_fd;
struct sockaddr_un addr;
size_t path_len;
+ _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
if (abstract)
{
-#ifdef HAVE_ABSTRACT_SOCKETS
+#ifdef __linux__
/* remember that abstract names aren't nul-terminated so we rely
* on sun_path being filled in with zeroes above.
*/
return -1;
}
- strncpy (&addr.sun_path[1], path, path_len);
+ strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
/* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
-#else /* HAVE_ABSTRACT_SOCKETS */
+#else /* !__linux__ */
dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
"Operating system does not support abstract socket namespace\n");
_dbus_close (listen_fd, NULL);
return -1;
-#endif /* ! HAVE_ABSTRACT_SOCKETS */
+#endif /* !__linux__ */
}
else
{
return -1;
}
- strncpy (addr.sun_path, path, path_len);
+ strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
}
if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
#endif
}
+/* Convert an error code from getaddrinfo() or getnameinfo() into
+ * a D-Bus error name. */
+static const char *
+_dbus_error_from_gai (int gai_res,
+ int saved_errno)
+{
+ switch (gai_res)
+ {
+#ifdef EAI_FAMILY
+ case EAI_FAMILY:
+ /* ai_family not supported (at all) */
+ return DBUS_ERROR_NOT_SUPPORTED;
+#endif
+
+#ifdef EAI_SOCKTYPE
+ case EAI_SOCKTYPE:
+ /* ai_socktype not supported (at all) */
+ return DBUS_ERROR_NOT_SUPPORTED;
+#endif
+
+#ifdef EAI_MEMORY
+ case EAI_MEMORY:
+ /* Out of memory */
+ return DBUS_ERROR_NO_MEMORY;
+#endif
+
+#ifdef EAI_SYSTEM
+ case EAI_SYSTEM:
+ /* Unspecified system error, details in errno */
+ return _dbus_error_from_errno (saved_errno);
+#endif
+
+ case 0:
+ /* It succeeded, but we didn't get any addresses? */
+ return DBUS_ERROR_FAILED;
+
+ /* EAI_AGAIN: Transient failure */
+ /* EAI_BADFLAGS: invalid ai_flags (programming error) */
+ /* EAI_FAIL: Non-recoverable failure */
+ /* EAI_NODATA: host exists but has no addresses */
+ /* EAI_NONAME: host does not exist */
+ /* EAI_OVERFLOW: argument buffer overflow */
+ /* EAI_SERVICE: service not available for specified socket
+ * type (we should never see this because we use numeric
+ * ports) */
+ default:
+ return DBUS_ERROR_FAILED;
+ }
+}
+
/**
* Creates a socket and connects to a socket at the given host
* and port. The connection fd is returned, and is set up as
if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
{
dbus_set_error (error,
- _dbus_error_from_errno (errno),
+ _dbus_error_from_gai (res, errno),
"Failed to lookup host/port: \"%s:%s\": %s (%d)",
host, port, gai_strerror(res), res);
return _dbus_socket_get_invalid ();
if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
{
dbus_set_error (error,
- _dbus_error_from_errno (errno),
+ _dbus_error_from_gai (res, errno),
"Failed to lookup host/port: \"%s:%s\": %s (%d)",
host ? host : "*", port, gai_strerror(res), res);
goto failed;
newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
if (!newlisten_fd)
{
- saved_errno = errno;
_dbus_close (fd, NULL);
- dbus_set_error (error, _dbus_error_from_errno (saved_errno),
- "Failed to allocate file handle array: %s",
- _dbus_strerror (saved_errno));
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
+ "Failed to allocate file handle array");
goto failed;
}
listen_fd = newlisten_fd;
addrlen = sizeof(addr);
result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
- if (result == -1 ||
- (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
+ if (result == -1)
+ {
+ saved_errno = errno;
+ dbus_set_error (error, _dbus_error_from_errno (saved_errno),
+ "Failed to retrieve socket name for \"%s:%s\": %s",
+ host ? host : "*", port, _dbus_strerror (saved_errno));
+ goto failed;
+ }
+
+ if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
portbuf, sizeof(portbuf),
NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
{
- dbus_set_error (error, _dbus_error_from_errno (errno),
+ saved_errno = errno;
+ dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
"Failed to resolve port \"%s:%s\": %s (%d)",
host ? host : "*", port, gai_strerror(res), res);
goto failed;
}
+
if (!_dbus_string_append(retport, portbuf))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
ucred_t * ucred = NULL;
if (getpeerucred (client_fd.fd, &ucred) == 0)
{
+#ifdef HAVE_ADT
+ adt_session_data_t *adth = NULL;
+#endif
pid_read = ucred_getpid (ucred);
uid_read = ucred_geteuid (ucred);
#ifdef HAVE_ADT
/* generate audit session data based on socket ucred */
- adt_session_data_t *adth = NULL;
- adt_export_data_t *data = NULL;
- size_t size = 0;
if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
{
_dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
}
else
{
- size = adt_export_session_data (adth, &data);
+ adt_export_data_t *data = NULL;
+ size_t size = adt_export_session_data (adth, &data);
if (size <= 0)
{
_dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
* @returns #TRUE on success
*/
dbus_bool_t
-_dbus_create_directory (const DBusString *filename,
+_dbus_ensure_directory (const DBusString *filename,
DBusError *error)
{
const char *filename_c;
}
/**
+ * Creates a directory. Unlike _dbus_ensure_directory(), this only succeeds
+ * if the directory is genuinely newly-created.
+ *
+ * @param filename directory filename
+ * @param error initialized error object
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+_dbus_create_directory (const DBusString *filename,
+ DBusError *error)
+{
+ const char *filename_c;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ filename_c = _dbus_string_get_const_data (filename);
+
+ if (mkdir (filename_c, 0700) < 0)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Failed to create directory %s: %s\n",
+ filename_c, _dbus_strerror (errno));
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+/**
* Appends the given filename to the given directory.
*
* @todo it might be cute to collapse multiple '/' such as "foo//"
dbus_bool_t create_if_not_found,
DBusError *error)
{
+ DBusError our_error = DBUS_ERROR_INIT;
+ DBusError etc_error = DBUS_ERROR_INIT;
DBusString filename;
dbus_bool_t b;
_dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
- b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
+ b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
if (b)
return TRUE;
- dbus_error_free (error);
-
/* Fallback to the system machine ID */
_dbus_string_init_const (&filename, "/etc/machine-id");
- b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
+ b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
if (b)
{
- /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
- * complain if that isn't possible for whatever reason */
- _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
- _dbus_write_uuid_file (&filename, machine_id, NULL);
+ if (create_if_not_found)
+ {
+ /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
+ * complain if that isn't possible for whatever reason */
+ _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
+ _dbus_write_uuid_file (&filename, machine_id, NULL);
+ }
+ dbus_error_free (&our_error);
return TRUE;
}
if (!create_if_not_found)
- return FALSE;
+ {
+ dbus_set_error (error, etc_error.name,
+ "D-Bus library appears to be incorrectly set up: "
+ "see the manual page for dbus-uuidgen to correct "
+ "this issue. (%s; %s)",
+ our_error.message, etc_error.message);
+ dbus_error_free (&our_error);
+ dbus_error_free (&etc_error);
+ return FALSE;
+ }
+
+ dbus_error_free (&our_error);
+ dbus_error_free (&etc_error);
/* if none found, try to make a new one */
- dbus_error_free (error);
_dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
if (!_dbus_generate_uuid (machine_id, error))
static dbus_bool_t already_warned = FALSE;
if (!already_warned)
{
- _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid");
+ _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
+ _dbus_string_get_const_data (&homedir));
already_warned = TRUE;
}
}
dbus_bool_t
_dbus_get_is_errno_eagain_or_ewouldblock (int e)
{
+ /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
+ * EWOULDBLOCK are numerically equal, which is permitted as described by
+ * errno(3).
+ */
+#if EAGAIN == EWOULDBLOCK
+ return e == EAGAIN;
+#else
return e == EAGAIN || e == EWOULDBLOCK;
+#endif
}
/**
* @param severity a severity value
* @param msg a printf-style format string
* @param args arguments for the format string
- *
- * If the FATAL severity is given, this function will terminate the program
- * with an error code.
*/
void
_dbus_logv (DBusSystemLogSeverity severity,
switch (severity)
{
case DBUS_SYSTEM_LOG_INFO:
- flags = LOG_DAEMON | LOG_NOTICE;
+ flags = LOG_DAEMON | LOG_INFO;
break;
case DBUS_SYSTEM_LOG_WARNING:
flags = LOG_DAEMON | LOG_WARNING;
case DBUS_SYSTEM_LOG_SECURITY:
flags = LOG_AUTH | LOG_NOTICE;
break;
- case DBUS_SYSTEM_LOG_FATAL:
+ case DBUS_SYSTEM_LOG_ERROR:
flags = LOG_DAEMON|LOG_CRIT;
break;
default:
- return;
+ _dbus_assert_not_reached ("invalid log severity");
}
DBUS_VA_COPY (tmp, args);
fputc ('\n', stderr);
va_end (tmp);
}
-
- if (severity == DBUS_SYSTEM_LOG_FATAL)
- exit (1);
}
/* tests in dbus-sysdeps-util.c */