]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/notify/notify.c
tmpfiles: fix help text
[thirdparty/systemd.git] / src / notify / notify.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4a2a8b5a
LP
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
4a2a8b5a
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
4a2a8b5a 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
4a2a8b5a
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdio.h>
23#include <getopt.h>
4a2a8b5a
LP
24#include <errno.h>
25#include <unistd.h>
26#include <stdlib.h>
27#include <string.h>
28
73f860db 29#include "systemd/sd-daemon.h"
81527be1 30
4a2a8b5a
LP
31#include "strv.h"
32#include "util.h"
33#include "log.h"
9aac0b2c 34#include "build.h"
4d1a6904 35#include "env-util.h"
4a2a8b5a
LP
36
37static bool arg_ready = false;
38static pid_t arg_pid = 0;
39static const char *arg_status = NULL;
96551bae 40static bool arg_booted = false;
4a2a8b5a 41
601185b4 42static void help(void) {
2e33c433 43 printf("%s [OPTIONS...] [VARIABLE=VALUE...]\n\n"
4a2a8b5a 44 "Notify the init system about service status updates.\n\n"
6624768c 45 " -h --help Show this help\n"
9aac0b2c 46 " --version Show package version\n"
6624768c
LP
47 " --ready Inform the init system about service start-up completion\n"
48 " --pid[=PID] Set main pid of daemon\n"
49 " --status=TEXT Set status text\n"
d6bc8348 50 " --booted Returns 0 if the system was booted up with systemd, non-zero otherwise\n",
4a2a8b5a 51 program_invocation_short_name);
4a2a8b5a
LP
52}
53
54static int parse_argv(int argc, char *argv[]) {
55
56 enum {
57 ARG_READY = 0x100,
9aac0b2c 58 ARG_VERSION,
4a2a8b5a 59 ARG_PID,
96551bae 60 ARG_STATUS,
6624768c 61 ARG_BOOTED,
4a2a8b5a
LP
62 };
63
64 static const struct option options[] = {
6624768c 65 { "help", no_argument, NULL, 'h' },
9aac0b2c 66 { "version", no_argument, NULL, ARG_VERSION },
6624768c
LP
67 { "ready", no_argument, NULL, ARG_READY },
68 { "pid", optional_argument, NULL, ARG_PID },
69 { "status", required_argument, NULL, ARG_STATUS },
70 { "booted", no_argument, NULL, ARG_BOOTED },
eb9da376 71 {}
4a2a8b5a
LP
72 };
73
74 int c;
75
76 assert(argc >= 0);
77 assert(argv);
78
ee8c4568 79 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
4a2a8b5a
LP
80
81 switch (c) {
82
83 case 'h':
601185b4
ZJS
84 help();
85 return 0;
4a2a8b5a 86
9aac0b2c
LP
87 case ARG_VERSION:
88 puts(PACKAGE_STRING);
9aac0b2c
LP
89 puts(SYSTEMD_FEATURES);
90 return 0;
91
4a2a8b5a
LP
92 case ARG_READY:
93 arg_ready = true;
94 break;
95
96 case ARG_PID:
97
98 if (optarg) {
99 if (parse_pid(optarg, &arg_pid) < 0) {
100 log_error("Failed to parse PID %s.", optarg);
101 return -EINVAL;
102 }
103 } else
104 arg_pid = getppid();
105
106 break;
107
108 case ARG_STATUS:
109 arg_status = optarg;
110 break;
111
96551bae
LP
112 case ARG_BOOTED:
113 arg_booted = true;
114 break;
115
4a2a8b5a
LP
116 case '?':
117 return -EINVAL;
118
119 default:
eb9da376 120 assert_not_reached("Unhandled option");
4a2a8b5a 121 }
ee8c4568 122 }
4a2a8b5a 123
2f02ce40
LP
124 if (optind >= argc &&
125 !arg_ready &&
126 !arg_status &&
127 !arg_pid &&
d6bc8348 128 !arg_booted) {
2f02ce40
LP
129 help();
130 return -EINVAL;
131 }
132
4a2a8b5a
LP
133 return 1;
134}
135
136int main(int argc, char* argv[]) {
be8f4e9e
LP
137 _cleanup_free_ char *status = NULL, *cpid = NULL, *n = NULL;
138 _cleanup_strv_free_ char **final_env = NULL;
139 char* our_env[4];
4a2a8b5a 140 unsigned i = 0;
be8f4e9e 141 int r;
4a2a8b5a
LP
142
143 log_parse_environment();
2396fb04 144 log_open();
4a2a8b5a 145
6c12b52e 146 r = parse_argv(argc, argv);
be8f4e9e 147 if (r <= 0)
4a2a8b5a 148 goto finish;
4a2a8b5a 149
96551bae
LP
150 if (arg_booted)
151 return sd_booted() <= 0;
152
4a2a8b5a
LP
153 if (arg_ready)
154 our_env[i++] = (char*) "READY=1";
155
156 if (arg_status) {
be8f4e9e
LP
157 status = strappend("STATUS=", arg_status);
158 if (!status) {
159 r = log_oom();
4a2a8b5a
LP
160 goto finish;
161 }
162
163 our_env[i++] = status;
164 }
165
166 if (arg_pid > 0) {
de0671ee 167 if (asprintf(&cpid, "MAINPID="PID_FMT, arg_pid) < 0) {
be8f4e9e 168 r = log_oom();
4a2a8b5a
LP
169 goto finish;
170 }
171
172 our_env[i++] = cpid;
173 }
174
175 our_env[i++] = NULL;
176
be8f4e9e
LP
177 final_env = strv_env_merge(2, our_env, argv + optind);
178 if (!final_env) {
179 r = log_oom();
4a2a8b5a
LP
180 goto finish;
181 }
182
183 if (strv_length(final_env) <= 0) {
be8f4e9e 184 r = 0;
4a2a8b5a
LP
185 goto finish;
186 }
187
be8f4e9e
LP
188 n = strv_join(final_env, "\n");
189 if (!n) {
190 r = log_oom();
4a2a8b5a
LP
191 goto finish;
192 }
193
be8f4e9e
LP
194 r = sd_pid_notify(arg_pid, false, n);
195 if (r < 0) {
da927ba9 196 log_error_errno(r, "Failed to notify init system: %m");
4a2a8b5a
LP
197 goto finish;
198 }
199
be8f4e9e
LP
200 if (r == 0)
201 r = -ENOTSUP;
4a2a8b5a
LP
202
203finish:
be8f4e9e 204 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
4a2a8b5a 205}