/src/systemd/src/shared/service-util.c
Line | Count | Source |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | |
3 | | #include <getopt.h> |
4 | | #include <stdio.h> |
5 | | |
6 | | #include "alloc-util.h" |
7 | | #include "build.h" |
8 | | #include "bus-object.h" |
9 | | #include "log.h" |
10 | | #include "pretty-print.h" |
11 | | #include "runtime-scope.h" |
12 | | #include "service-util.h" |
13 | | |
14 | | typedef enum HelpFlags { |
15 | | HELP_WITH_BUS_INTROSPECT = 1 << 0, |
16 | | HELP_WITH_RUNTIME_SCOPE = 1 << 1, |
17 | | } HelpFlags; |
18 | | |
19 | | static int help(const char *program_path, |
20 | | const char *service, |
21 | | const char *description, |
22 | 0 | HelpFlags flags) { |
23 | |
|
24 | 0 | _cleanup_free_ char *link = NULL; |
25 | 0 | int r; |
26 | |
|
27 | 0 | r = terminal_urlify_man(service, "8", &link); |
28 | 0 | if (r < 0) |
29 | 0 | return log_oom(); |
30 | | |
31 | 0 | printf("%1$s [OPTIONS...]\n" |
32 | 0 | "\n%5$s%7$s%6$s\n" |
33 | 0 | "\nThis program takes no positional arguments.\n" |
34 | 0 | "\n%3$sOptions:%4$s\n" |
35 | 0 | " -h --help Show this help\n" |
36 | 0 | " --version Show package version\n" |
37 | 0 | "%8$s" |
38 | 0 | "%9$s" |
39 | 0 | "\nSee the %2$s for details.\n", |
40 | 0 | program_path, |
41 | 0 | link, |
42 | 0 | ansi_underline(), |
43 | 0 | ansi_normal(), |
44 | 0 | ansi_highlight(), |
45 | 0 | ansi_normal(), |
46 | 0 | description, |
47 | 0 | FLAGS_SET(flags, HELP_WITH_BUS_INTROSPECT) ? " --bus-introspect=PATH Write D-Bus XML introspection data\n" : "", |
48 | 0 | FLAGS_SET(flags, HELP_WITH_RUNTIME_SCOPE) ? " --system Start service in system mode\n" |
49 | 0 | " --user Start service in user mode\n" : ""); |
50 | |
|
51 | 0 | return 0; /* No further action */ |
52 | 0 | } |
53 | | |
54 | | int service_parse_argv( |
55 | | const char *service, |
56 | | const char *description, |
57 | | const BusObjectImplementation* const* bus_objects, |
58 | | RuntimeScope *runtime_scope, |
59 | 0 | int argc, char *argv[]) { |
60 | |
|
61 | 0 | enum { |
62 | 0 | ARG_VERSION = 0x100, |
63 | 0 | ARG_BUS_INTROSPECT, |
64 | 0 | ARG_SYSTEM, |
65 | 0 | ARG_USER, |
66 | 0 | }; |
67 | |
|
68 | 0 | static const struct option options[] = { |
69 | 0 | { "help", no_argument, NULL, 'h' }, |
70 | 0 | { "version", no_argument, NULL, ARG_VERSION }, |
71 | 0 | { "bus-introspect", required_argument, NULL, ARG_BUS_INTROSPECT }, |
72 | 0 | { "system", no_argument, NULL, ARG_SYSTEM }, |
73 | 0 | { "user", no_argument, NULL, ARG_USER }, |
74 | 0 | {} |
75 | 0 | }; |
76 | |
|
77 | 0 | int c; |
78 | |
|
79 | 0 | assert(argc >= 0); |
80 | 0 | assert(argv); |
81 | |
|
82 | 0 | while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) |
83 | 0 | switch (c) { |
84 | | |
85 | 0 | case 'h': |
86 | 0 | return help(argv[0], |
87 | 0 | service, |
88 | 0 | description, |
89 | 0 | (bus_objects ? HELP_WITH_BUS_INTROSPECT : 0) | |
90 | 0 | (runtime_scope ? HELP_WITH_RUNTIME_SCOPE : 0)); |
91 | | |
92 | 0 | case ARG_VERSION: |
93 | 0 | return version(); |
94 | | |
95 | 0 | case ARG_BUS_INTROSPECT: |
96 | 0 | return bus_introspect_implementations( |
97 | 0 | stdout, |
98 | 0 | optarg, |
99 | 0 | bus_objects); |
100 | | |
101 | 0 | case ARG_SYSTEM: |
102 | 0 | case ARG_USER: |
103 | 0 | if (!runtime_scope) |
104 | 0 | return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This service cannot be run in --system or --user mode, refusing."); |
105 | | |
106 | 0 | *runtime_scope = c == ARG_SYSTEM ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER; |
107 | 0 | break; |
108 | | |
109 | 0 | case '?': |
110 | 0 | return -EINVAL; |
111 | | |
112 | 0 | default: |
113 | 0 | assert_not_reached(); |
114 | 0 | } |
115 | | |
116 | 0 | if (optind < argc) |
117 | 0 | return log_error_errno(SYNTHETIC_ERRNO(EINVAL), |
118 | 0 | "This program takes no arguments."); |
119 | | |
120 | 0 | return 1; /* Further action */ |
121 | 0 | } |