1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include "format-table.h"
4 #include "parse-argument.h"
5 #include "path-util.h"
6 #include "signal-util.h"
7 #include "stdio-util.h"
8 #include "string-table.h"
9 #include "string-util.h"
10 
11 /* All functions in this file emit warnings. */
12 
parse_boolean_argument(const char * optname,const char * s,bool * ret)13 int parse_boolean_argument(const char *optname, const char *s, bool *ret) {
14         int r;
15 
16         /* Returns the result through *ret and the return value. */
17 
18         if (s) {
19                 r = parse_boolean(s);
20                 if (r < 0)
21                         return log_error_errno(r, "Failed to parse boolean argument to %s: %s.", optname, s);
22 
23                 if (ret)
24                         *ret = r;
25                 return r;
26         } else {
27                 /* s may be NULL. This is controlled by getopt_long() parameters. */
28                 if (ret)
29                         *ret = true;
30                 return true;
31         }
32 }
33 
parse_json_argument(const char * s,JsonFormatFlags * ret)34 int parse_json_argument(const char *s, JsonFormatFlags *ret) {
35         assert(s);
36         assert(ret);
37 
38         if (streq(s, "pretty"))
39                 *ret = JSON_FORMAT_PRETTY|JSON_FORMAT_COLOR_AUTO;
40         else if (streq(s, "short"))
41                 *ret = JSON_FORMAT_NEWLINE;
42         else if (streq(s, "off"))
43                 *ret = JSON_FORMAT_OFF;
44         else if (streq(s, "help")) {
45                 puts("pretty\n"
46                      "short\n"
47                      "off");
48                 return 0; /* 0 means → we showed a brief help, exit now */
49         } else
50                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown argument to --json= switch: %s", s);
51 
52         return 1; /* 1 means → properly parsed */
53 }
54 
parse_path_argument(const char * path,bool suppress_root,char ** arg)55 int parse_path_argument(const char *path, bool suppress_root, char **arg) {
56         char *p;
57         int r;
58 
59         /*
60          * This function is intended to be used in command line parsers, to handle paths that are passed
61          * in. It makes the path absolute, and reduces it to NULL if omitted or root (the latter optionally).
62          *
63          * NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON SUCCESS!
64          * Hence, do not pass in uninitialized pointers.
65          */
66 
67         if (isempty(path)) {
68                 *arg = mfree(*arg);
69                 return 0;
70         }
71 
72         r = path_make_absolute_cwd(path, &p);
73         if (r < 0)
74                 return log_error_errno(r, "Failed to parse path \"%s\" and make it absolute: %m", path);
75 
76         path_simplify(p);
77         if (suppress_root && empty_or_root(p))
78                 p = mfree(p);
79 
80         return free_and_replace(*arg, p);
81 }
82 
parse_signal_argument(const char * s,int * ret)83 int parse_signal_argument(const char *s, int *ret) {
84         int r;
85 
86         assert(s);
87         assert(ret);
88 
89         if (streq(s, "help")) {
90                 DUMP_STRING_TABLE(signal, int, _NSIG);
91                 return 0;
92         }
93 
94         if (streq(s, "list")) {
95                 _cleanup_(table_unrefp) Table *table = NULL;
96 
97                 table = table_new("signal", "name");
98                 if (!table)
99                         return log_oom();
100 
101                 for (int i = 1; i < _NSIG; i++) {
102                         r = table_add_many(
103                                         table,
104                                         TABLE_INT, i,
105                                         TABLE_SIGNAL, i);
106                         if (r < 0)
107                                 return table_log_add_error(r);
108                 }
109 
110                 r = table_print(table, NULL);
111                 if (r < 0)
112                         return table_log_print_error(r);
113 
114                 return 0;
115         }
116 
117         r = signal_from_string(s);
118         if (r < 0)
119                 return log_error_errno(r, "Failed to parse signal string \"%s\".", s);
120 
121         *ret = r;
122         return 1; /* work to do */
123 }
124