*/
#include <errno.h>
-#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
-#include <sys/types.h>
-#include <sys/poll.h>
+#include <poll.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include "socket-util.h"
+#include "formats-util.h"
#include "udev.h"
/* wire protocol magic must match */
int refcount;
struct udev *udev;
int sock;
- struct sockaddr_un saddr;
+ union sockaddr_union saddr;
socklen_t addrlen;
bool bound;
bool cleanup_socket;
uctrl->bound = true;
uctrl->sock = fd;
}
+
+ /*
+ * FIXME: remove it as soon as we can depend on this:
+ * http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=90c6bd34f884cd9cee21f1d152baf6c18bcac949
+ */
r = setsockopt(uctrl->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
if (r < 0)
log_warning_errno(errno, "could not set SO_PASSCRED: %m");
- uctrl->saddr.sun_family = AF_LOCAL;
- strscpy(uctrl->saddr.sun_path, sizeof(uctrl->saddr.sun_path), "/run/udev/control");
- uctrl->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(uctrl->saddr.sun_path);
+ uctrl->saddr.un.sun_family = AF_LOCAL;
+ strscpy(uctrl->saddr.un.sun_path, sizeof(uctrl->saddr.un.sun_path), "/run/udev/control");
+ uctrl->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(uctrl->saddr.un.sun_path);
return uctrl;
}
int err;
if (!uctrl->bound) {
- err = bind(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen);
+ err = bind(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen);
if (err < 0 && errno == EADDRINUSE) {
- unlink(uctrl->saddr.sun_path);
- err = bind(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen);
+ unlink(uctrl->saddr.un.sun_path);
+ err = bind(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen);
}
- if (err < 0) {
- err = -errno;
- log_error_errno(errno, "bind failed: %m");
- return err;
- }
+ if (err < 0)
+ return log_error_errno(errno, "bind failed: %m");
err = listen(uctrl->sock, 0);
- if (err < 0) {
- err = -errno;
- log_error_errno(errno, "listen failed: %m");
- return err;
- }
+ if (err < 0)
+ return log_error_errno(errno, "listen failed: %m");
uctrl->bound = true;
uctrl->cleanup_socket = true;
}
static struct udev_ctrl *udev_ctrl_ref(struct udev_ctrl *uctrl) {
- if (uctrl == NULL)
- return NULL;
- uctrl->refcount++;
+ if (uctrl)
+ uctrl->refcount++;
+
return uctrl;
}
struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl) {
- if (uctrl == NULL)
- return NULL;
- uctrl->refcount--;
- if (uctrl->refcount > 0)
- return uctrl;
- if (uctrl->sock >= 0)
- close(uctrl->sock);
- free(uctrl);
+ if (uctrl && -- uctrl->refcount == 0) {
+ if (uctrl->sock >= 0)
+ close(uctrl->sock);
+ free(uctrl);
+ }
+
return NULL;
}
if (uctrl == NULL)
return 0;
if (uctrl->cleanup_socket)
- unlink(uctrl->saddr.sun_path);
+ unlink(uctrl->saddr.un.sun_path);
return 0;
}
goto err;
}
if (ucred.uid > 0) {
- log_error("sender uid=%i, message ignored", ucred.uid);
+ log_error("sender uid="UID_FMT", message ignored", ucred.uid);
goto err;
}
}
struct udev_ctrl_connection *udev_ctrl_connection_unref(struct udev_ctrl_connection *conn) {
- if (conn == NULL)
- return NULL;
- conn->refcount--;
- if (conn->refcount > 0)
- return conn;
- if (conn->sock >= 0)
- close(conn->sock);
- udev_ctrl_unref(conn->uctrl);
- free(conn);
+ if (conn && -- conn->refcount == 0) {
+ if (conn->sock >= 0)
+ close(conn->sock);
+
+ udev_ctrl_unref(conn->uctrl);
+
+ free(conn);
+ }
+
return NULL;
}
ctrl_msg_wire.intval = intval;
if (!uctrl->connected) {
- if (connect(uctrl->sock, (struct sockaddr *)&uctrl->saddr, uctrl->addrlen) < 0) {
+ if (connect(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen) < 0) {
err = -errno;
goto out;
}
log_error_errno(errno, "unable to receive ctrl message: %m");
goto err;
}
+
+ cmsg_close_all(&smsg);
+
cmsg = CMSG_FIRSTHDR(&smsg);
- cred = (struct ucred *) CMSG_DATA(cmsg);
if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
log_error("no sender credentials received, message ignored");
goto err;
}
+ cred = (struct ucred *) CMSG_DATA(cmsg);
+
if (cred->uid != 0) {
- log_error("sender uid=%i, message ignored", cred->uid);
+ log_error("sender uid="UID_FMT", message ignored", cred->uid);
goto err;
}
}
struct udev_ctrl_msg *udev_ctrl_msg_unref(struct udev_ctrl_msg *ctrl_msg) {
- if (ctrl_msg == NULL)
- return NULL;
- ctrl_msg->refcount--;
- if (ctrl_msg->refcount > 0)
- return ctrl_msg;
- udev_ctrl_connection_unref(ctrl_msg->conn);
- free(ctrl_msg);
+ if (ctrl_msg && -- ctrl_msg->refcount == 0) {
+ udev_ctrl_connection_unref(ctrl_msg->conn);
+ free(ctrl_msg);
+ }
+
return NULL;
}