1 /*
2  * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
3  * Copyright (c) 2015 Laurent COUSTET <ed@zehome.com>
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include "mlvpn.h"
19 #include "systemd.h"
20 
21 /**
22  * Tell if we have been started by systemd.
23  */
24 void
mlvpn_systemd_notify()25 mlvpn_systemd_notify()
26 {
27     int fd = -1;
28     const char *notifysocket = getenv("NOTIFY_SOCKET");
29     if (!notifysocket ||
30         !strchr("@/", notifysocket[0]) ||
31         strlen(notifysocket) < 2)
32         return;
33 
34     log_debug("systemd",
35         "running with systemd, don't fork but signal ready");
36     if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
37         log_warn("systemd",
38             "unable to open systemd notification socket %s",
39             notifysocket);
40         return;
41     }
42 
43     struct sockaddr_un su = { .sun_family = AF_UNIX };
44     strlcpy(su.sun_path, notifysocket, sizeof(su.sun_path));
45     if (notifysocket[0] == '@') su.sun_path[0] = 0;
46 
47     struct iovec iov = {
48         .iov_base = "READY=1",
49         .iov_len = strlen("READY=1")
50     };
51     struct msghdr hdr = {
52         .msg_name = &su,
53         .msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(notifysocket),
54         .msg_iov = &iov,
55         .msg_iovlen = 1
56     };
57     unsetenv("NOTIFY_SOCKET");
58     if (sendmsg(fd, &hdr, MSG_NOSIGNAL) < 0) {
59         log_warn("systemd",
60             "unable to send notification to systemd");
61         close(fd);
62         return;
63     }
64     close(fd);
65 }
66