mirror of
https://git.freebsd.org/ports.git
synced 2025-04-30 02:26:38 -04:00
PR: 249549 PR: 249550 PR: 249570 PR: 249734 PR: 249735 PR: 249738 Approved by: desktop (tcberner) Obtained from: ArchLinux, see Bugzilla PRs for details
181 lines
4.6 KiB
C
181 lines
4.6 KiB
C
--- lib/gibber/gibber-unix-transport.c.orig 2013-10-04 15:51:47 UTC
|
|
+++ lib/gibber/gibber-unix-transport.c
|
|
@@ -374,6 +374,167 @@ gibber_unix_transport_recv_credentials (GibberUnixTran
|
|
return TRUE;
|
|
}
|
|
|
|
+/* End Linux part */
|
|
+#elif defined(__FreeBSD__)
|
|
+
|
|
+gboolean
|
|
+gibber_unix_transport_send_credentials (GibberUnixTransport *transport,
|
|
+ const guint8 *data,
|
|
+ gsize size)
|
|
+{
|
|
+ int fd, ret;
|
|
+ struct msghdr msg;
|
|
+ struct iovec iov;
|
|
+ union {
|
|
+ struct cmsghdr hdr;
|
|
+ char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
|
|
+ } cmsg;
|
|
+
|
|
+ DEBUG ("send credentials");
|
|
+ fd = GIBBER_FD_TRANSPORT (transport)->fd;
|
|
+
|
|
+ /* Set the message payload */
|
|
+ memset (&iov, 0, sizeof (iov));
|
|
+ iov.iov_base = (void *) data;
|
|
+ iov.iov_len = size;
|
|
+
|
|
+ memset (&msg, 0, sizeof (msg));
|
|
+ msg.msg_iov = &iov;
|
|
+ msg.msg_iovlen = 1;
|
|
+ msg.msg_control = (caddr_t) &cmsg;
|
|
+ msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
|
|
+ memset (&cmsg, 0, sizeof (cmsg));
|
|
+ cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
|
|
+ cmsg.hdr.cmsg_level = SOL_SOCKET;
|
|
+ cmsg.hdr.cmsg_type = SCM_CREDS;
|
|
+
|
|
+ ret = sendmsg (fd, &msg, 0);
|
|
+ if (ret == -1)
|
|
+ {
|
|
+ DEBUG ("sendmsg failed: %s", g_strerror (errno));
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+gboolean
|
|
+gibber_unix_transport_recv_credentials (GibberUnixTransport *self,
|
|
+ GibberUnixTransportRecvCredentialsCb callback,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ GibberUnixTransportPrivate *priv = GIBBER_UNIX_TRANSPORT_GET_PRIVATE (self);
|
|
+
|
|
+ if (priv->recv_creds_cb != NULL)
|
|
+ {
|
|
+ DEBUG ("already waiting for credentials");
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ priv->recv_creds_cb = callback;
|
|
+ priv->recv_creds_data = user_data;
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+gboolean
|
|
+gibber_unix_transport_supports_credentials (void)
|
|
+{
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+#define BUFSIZE 1024
|
|
+
|
|
+static GibberFdIOResult
|
|
+gibber_unix_transport_read (GibberFdTransport *transport,
|
|
+ GIOChannel *channel,
|
|
+ GError **error)
|
|
+{
|
|
+ GibberUnixTransport *self = GIBBER_UNIX_TRANSPORT (transport);
|
|
+ GibberUnixTransportPrivate *priv = GIBBER_UNIX_TRANSPORT_GET_PRIVATE (self);
|
|
+ int fd;
|
|
+ guint8 buffer[BUFSIZE];
|
|
+ ssize_t bytes_read;
|
|
+ GibberBuffer buf;
|
|
+ struct iovec iov;
|
|
+ struct msghdr msg;
|
|
+ struct cmsgcred *cred;
|
|
+ union {
|
|
+ struct cmsghdr hdr;
|
|
+ char cred[CMSG_SPACE (sizeof *cred)];
|
|
+ } cmsg;
|
|
+ int opt;
|
|
+
|
|
+ if (priv->recv_creds_cb == NULL)
|
|
+ return gibber_fd_transport_read (transport, channel, error);
|
|
+
|
|
+ /* We are waiting for credentials */
|
|
+ fd = transport->fd;
|
|
+
|
|
+ memset (buffer, 0, sizeof (buffer));
|
|
+ memset (&iov, 0, sizeof (iov));
|
|
+ iov.iov_base = buffer;
|
|
+ iov.iov_len = sizeof (buffer);
|
|
+
|
|
+ memset (&msg, 0, sizeof (msg));
|
|
+ msg.msg_iov = &iov;
|
|
+ msg.msg_iovlen = 1;
|
|
+ msg.msg_control = (caddr_t) &cmsg;
|
|
+ msg.msg_controllen = CMSG_SPACE (sizeof *cred);
|
|
+
|
|
+ bytes_read = recvmsg (fd, &msg, 0);
|
|
+
|
|
+ if (bytes_read == -1)
|
|
+ {
|
|
+ GError *err = NULL;
|
|
+
|
|
+ g_set_error_literal (&err, G_IO_CHANNEL_ERROR,
|
|
+ g_io_channel_error_from_errno (errno), "recvmsg failed");
|
|
+
|
|
+ priv->recv_creds_cb (self, NULL, NULL, err, priv->recv_creds_data);
|
|
+ g_propagate_error (error, err);
|
|
+
|
|
+ priv->recv_creds_cb = NULL;
|
|
+ priv->recv_creds_data = NULL;
|
|
+ return GIBBER_FD_IO_RESULT_ERROR;
|
|
+ }
|
|
+
|
|
+ buf.data = buffer;
|
|
+ buf.length = bytes_read;
|
|
+
|
|
+ /* extract the credentials */
|
|
+ if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof *cred) ||
|
|
+ cmsg.hdr.cmsg_type != SCM_CREDS)
|
|
+ {
|
|
+ GError *err = NULL;
|
|
+
|
|
+ DEBUG ("Message doesn't contain credentials");
|
|
+
|
|
+ g_set_error_literal (&err, GIBBER_UNIX_TRANSPORT_ERROR,
|
|
+ GIBBER_UNIX_TRANSPORT_ERROR_NO_CREDENTIALS,
|
|
+ "no credentials received");
|
|
+
|
|
+ priv->recv_creds_cb (self, &buf, NULL, err, priv->recv_creds_data);
|
|
+ g_error_free (err);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ GibberCredentials credentials;
|
|
+
|
|
+ cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
|
|
+ credentials.pid = cred->cmcred_pid;
|
|
+ credentials.uid = cred->cmcred_uid;
|
|
+ credentials.gid = cred->cmcred_gid;
|
|
+
|
|
+ priv->recv_creds_cb (self, &buf, &credentials, NULL,
|
|
+ priv->recv_creds_data);
|
|
+ }
|
|
+
|
|
+ priv->recv_creds_cb = NULL;
|
|
+ priv->recv_creds_data = NULL;
|
|
+ return GIBBER_FD_IO_RESULT_SUCCESS;
|
|
+}
|
|
+
|
|
+/* End FreeBSD part */
|
|
#else /* OSs where we have no implementation */
|
|
|
|
gboolean
|
|
@@ -392,9 +553,7 @@ gibber_unix_transport_recv_credentials (GibberUnixTran
|
|
}
|
|
|
|
gboolean
|
|
-gibber_unix_transport_send_credentials (GibberUnixTransport *transport,
|
|
- const guint8 *data,
|
|
- gsize size)
|
|
+gibber_unix_transport_send_credentials (void)
|
|
{
|
|
DEBUG ("stub implementation, failing");
|
|
return FALSE;
|