libreport 2.13.1
A tool to inform users about various problems on the running system
run_event.h
1/*
2 Copyright (C) 2009 ABRT team.
3 Copyright (C) 2009 RedHat inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18*/
19#ifndef LIBREPORT_RUN_EVENT_H_
20#define LIBREPORT_RUN_EVENT_H_
21
22#include "problem_data.h"
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28struct dump_dir;
29
31 int children_count;
32
33 /* Used only for post-create dup detection. TODO: document its API */
34 int (*post_run_callback)(const char *dump_dir_name, void *param);
35 void *post_run_param;
36
37 /* Can take ownership of log_line, which is malloced. In this case, return NULL.
38 * Otherwise should return log_line (it will be freed by caller)
39 *
40 * The default value prints log_line with trailing newline to stdout.
41 */
42 char* (*logging_callback)(char *log_line, void *param);
43 void *logging_param;
44
45 /*
46 * Called if any error occures during communication with child's command.
47 *
48 * The default value prints error_line with trailing newline to stderr and
49 * exits with an error code.
50 *
51 * @param error_line An error message
52 * @param param a custom param
53 */
54 void (*error_callback)(const char *error_line, void *param);
55 void *error_param;
56
57 /*
58 * An optional argument for the following callbacks
59 */
60 void *interaction_param;
61
62 /*
63 * Called when child command produced an alert.
64 *
65 * The default value is run_event_stdio_alert()
66 *
67 * @param msg An alert message produced byt child command
68 * @param args An interaction param
69 */
70 void (*alert_callback)(const char *msg, void *interaction_param);
71
72 /*
73 * Called when child command ask for some input. A callee
74 * should return a text whithout any new line character.
75 *
76 * The default value is run_event_stdio_ask()
77 *
78 * @param msg An ask message produced by child command
79 * @param args An interaction param
80 * @return Must allways return string without new lines, an empty string
81 * if response was not get.
82 */
83 char *(*ask_callback)(const char *msg, void *interaction_param);
84
85 /*
86 * Called when child command wants to know 'yes/no' decision.
87 *
88 * The default value is run_event_stdio_ask_yes_no()
89 *
90 * @param msg An ask message produced by child command
91 * @param args An implementor args
92 * @return Return 0 if an answer is NO, otherwise return nonzero value.
93 */
94 int (*ask_yes_no_callback)(const char *msg, void *interaction_param);
95
96 /*
97 * Called when child command wants to know 'yes/no/yesforever' decision.
98 * The yes forever means that in next call the yes answer is returned
99 * immediately without asking. The yes forever answer is stored in
100 * configuration under a passed key.
101 *
102 * The default value is run_event_stdio_ask_yes_no_yesforever()
103 *
104 * @param key An option name used as a key in configuration
105 * @param msg An ask message produced by child command
106 * @param args An implementor args
107 * @return Return 0 if an answer is NO, otherwise return nonzero value.
108 */
109 int (*ask_yes_no_yesforever_callback)(const char *key, const char *msg, void *interaction_param);
110
111 /*
112 * Called when child command wants to know 'yes/no/forever/never' decision.
113 * The forever means that in next call the yes answer is returned
114 * immediately without asking. The never means that in next call the
115 * no answer is returned immediately without asking. The answer is stored
116 * in configuration under a passed key.
117 *
118 * The default value is run_event_stdio_ask_yes_no_save_result()
119 *
120 * @param key An option name used as a key in configuration
121 * @param msg An ask message produced by child command
122 * @param args An implementor args
123 * @return Return 0 if an answer is NO, otherwise return nonzero value.
124 */
125 int (*ask_yes_no_save_result_callback)(const char *key, const char *msg, void *interaction_param);
126
127 /*
128 * Called when child wants to know a password.
129 *
130 * The default value is run_event_stdio_ask_password()
131 *
132 * @param msg An ask message produced by child command
133 * @param args An interaction param
134 * @return Must allways return string without new lines, an empty string
135 * if password was not get.
136 */
137 char *(*ask_password_callback)(const char *msg, void *interaction_param);
138
139 GPtrArray *extra_environment;
140
141 /* Internal data for async command execution */
142 GList *rule_list;
143 pid_t command_pid;
144 int command_out_fd;
145 int command_in_fd;
146 int process_status;
147 struct strbuf *command_output;
148};
149struct run_event_state *new_run_event_state(void);
150void free_run_event_state(struct run_event_state *state);
151
152/*
153 * Configure callbacks to forward requests
154 *
155 * @param state A valid run event state pointer
156 */
157void make_run_event_state_forwarding(struct run_event_state *state);
158
159
160/* Asynchronous command execution */
161struct rule {
162 GList *conditions;
163 char *command; /* never NULL */
164};
165
166/* Returns 0 if no commands at all are defined for event processing, otherwise
167 * returns 1. */
168int prepare_commands(struct run_event_state *state);
169/*
170 * Returns -1 if no more commands needs to be executed,
171 * else sets state->command_pid and state->command_out_fd and returns >=0.
172 * execflags can be e.g. EXECFLG_SETPGID to put the event handling process
173 * into a new process group, EXECFLG_SETSID to put it in a new session, etc.
174 */
175int spawn_next_command(struct run_event_state *state,
176 const char *dump_dir_name,
177 const char *event,
178 unsigned execflags);
179/* Cleans up internal state created in prepare_commands */
180void free_commands(struct run_event_state *state);
181
182/* Load rule list from config file.
183 * Returns a list of all defined rules (struct rule)
184 * @param rule_list variable to append to or NONE to create new list
185 * @param conf_file_name path to configuration file
186 * @param recursion_depth internal recursion protection, should be 0
187 */
188GList *load_rule_list(GList *rule_list, const char *conf_file_name, unsigned recursion_depth);
189
190/* Cleans up rule list created by load_rule_list */
191void free_rule_list(GList *rule_list);
192
193/* Synchronous command execution */
194
195/* The function believes that a state param value is fully initialized and
196 * action is started.
197 *
198 * Returns exit code of action, or nonzero return value of post_run_callback
199 * If action is successful, returns 0.
200 *
201 * If return value is lower than 0 and you set O_NONBLOCK to command's out fd
202 * examine errno to detect EAGAIN case. Incomplete child lines are buffered
203 * in the state param.
204 */
205int consume_event_command_output(struct run_event_state *state, const char *dump_dir_name);
206
207/* Returns exit code of first failed action, or first nonzero return value
208 * of post_run_callback. If all actions are successful, returns 0.
209 */
210int run_event_on_dir_name(struct run_event_state *state, const char *dump_dir_name, const char *event);
211int run_event_on_problem_data(struct run_event_state *state, problem_data_t *data, const char *event);
212
213
214/* Querying for possible events */
215
216/* Scans event.conf for events starting with pfx which are applicable
217 * to dd, or (if dd is NULL), to dump_dir.
218 * Returns a malloced string with '\n'-terminated event names.
219 */
220char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const char *pfx);
221
222/* Like list_possible_events but accepts problem_data_t */
223char *list_possible_events_problem_data(problem_data_t *pd, const char *dump_dir_name, const char *pfx);
224
225/*
226 * Returns a list of possible events for given problem directory
227 *
228 * @param problem_dir_name the name of the problem directory
229 * @param pfx the prefix of the events "report", "workflow"
230 */
231GList *list_possible_events_glist(const char *problem_dir_name,
232 const char *pfx);
233
234/* Like list_possible_events_glist but accepts problem_data_t */
235GList *list_possible_events_problem_data_glist(problem_data_t *pd,
236 const char *problem_dir_name,
237 const char *pfx);
238
239/* Command line run event callback implemenetation */
240
241/*
242 * Prints the msg param on stdout
243 *
244 * @param msg a printed message
245 * @param param ONLY NULL IS ALLOWED; other values are intended for internal use only
246 */
247void run_event_stdio_alert(const char *msg, void *param);
248
249/*
250 * Prints the msg param on stdout and reads a response from stdin
251 *
252 * @param msg a printed message
253 * @param param ONLY NULL IS ALLOWED; other values are intended for internal use only
254 * @return a malloced string with response, an empty string on error or no response
255 */
256char *run_event_stdio_ask(const char *msg, void *param);
257
258/*
259 * Prints the msg param on stdout and reads a response from stdin
260 *
261 * @param msg a printed message
262 * @param param ONLY NULL IS ALLOWED; other values are intended for internal use only
263 * @return 0 if user's answer is 'no', otherwise non 0 value
264 */
265int run_event_stdio_ask_yes_no(const char *msg, void *param);
266
267/*
268 * Prints the msg param on stdout and reads a response from stdin. To store the
269 * yes forever answer uses libreport's user settings API. Therefore if you want
270 * to get the yes forever stuff working you have to call load_user_setting()
271 * function before this function call and call libreport_save_user_settings() function
272 * after this function call.
273 *
274 * @param msg a printed message
275 * @param key a key under which the yes forever answer is stored
276 * @param param ONLY NULL IS ALLOWED; other values are intended for internal use only
277 * @return 0 if user's answer is 'no', otherwise non 0 value
278 */
279int run_event_stdio_ask_yes_no_yesforever(const char *msg, const char *key, void *param);
280
281/*
282 * Prints the msg param on stdout and reads a response from stdin. To store the
283 * forever or never answer uses libreport's user settings API.
284 * Therefore if you want to get the forever or never stuff working you
285 * have to call load_user_setting() function before this function call and call
286 * libreport_save_user_settings() function after this function call.
287 *
288 * @param msg a printed message
289 * @param key a key under which the forever (yes) or never (no) answer is stored
290 * @param param ONLY NULL IS ALLOWED; other values are intended for internal use only
291 * @return 0 if user's answer is 'no', otherwise non 0 value
292 */
293int run_event_stdio_ask_yes_no_save_result(const char *msg, const char *key, void *param);
294
295/*
296 * Prints the msg param on stdout and reads a response from stdin
297 *
298 * @param msg a printed message
299 * @param param ONLY NULL IS ALLOWED; other values are intended for internal use only
300 * @return a malloced string with response, an empty string on error or no response
301 */
302char *run_event_stdio_ask_password(const char *msg, void *param);
303
304
305/* A simple helper */
306char *libreport_exit_status_as_string(const char *progname, int status);
307
308
309#ifdef __cplusplus
310}
311#endif
312
313#endif