1 /*
2     Task Spooler - a task queue system for the unix user
3     Copyright (C) 2007-2013  Lluís Batlle i Rossell
4 
5     Please find the license in the provided COPYING file.
6 */
7 enum
8 {
9     CMD_LEN=500,
10     PROTOCOL_VERSION=730
11 };
12 
13 enum msg_types
14 {
15     KILL_SERVER,
16     NEWJOB,
17     NEWJOB_OK,
18     RUNJOB,
19     RUNJOB_OK,
20     ENDJOB,
21     LIST,
22     LIST_LINE,
23     CLEAR_FINISHED,
24     ASK_OUTPUT,
25     ANSWER_OUTPUT,
26     REMOVEJOB,
27     REMOVEJOB_OK,
28     WAITJOB,
29     WAIT_RUNNING_JOB,
30     WAITJOB_OK,
31     URGENT,
32     URGENT_OK,
33     GET_STATE,
34     ANSWER_STATE,
35     SWAP_JOBS,
36     SWAP_JOBS_OK,
37     INFO,
38     INFO_DATA,
39     SET_MAX_SLOTS,
40     GET_MAX_SLOTS,
41     GET_MAX_SLOTS_OK,
42     GET_VERSION,
43     VERSION,
44     NEWJOB_NOK
45 };
46 
47 enum Request
48 {
49     c_QUEUE,
50     c_TAIL,
51     c_KILL_SERVER,
52     c_LIST,
53     c_CLEAR_FINISHED,
54     c_SHOW_HELP,
55     c_SHOW_VERSION,
56     c_CAT,
57     c_SHOW_OUTPUT_FILE,
58     c_SHOW_PID,
59     c_REMOVEJOB,
60     c_WAITJOB,
61     c_URGENT,
62     c_GET_STATE,
63     c_SWAP_JOBS,
64     c_INFO,
65     c_SET_MAX_SLOTS,
66     c_GET_MAX_SLOTS,
67     c_KILL_JOB
68 };
69 
70 struct Command_line {
71     enum Request request;
72     int need_server;
73     int store_output;
74     int stderr_apart;
75     int should_go_background;
76     int should_keep_finished;
77     int send_output_by_mail;
78     int gzip;
79     int do_depend;
80     int depend_on; /* -1 means depend on previous */
81     int max_slots; /* How many jobs to run at once */
82     int jobid; /* When queuing a job, main.c will fill it automatically from
83                   the server answer to NEWJOB */
84     int jobid2;
85     int wait_enqueuing;
86     struct {
87         char **array;
88         int num;
89     } command;
90     char *label;
91     int num_slots; /* Slots for the job to use. Default 1 */
92 };
93 
94 enum Process_type {
95     CLIENT,
96     SERVER
97 };
98 
99 extern struct Command_line command_line;
100 extern int server_socket;
101 extern enum Process_type process_type;
102 extern int server_socket; /* Used in the client */
103 
104 struct msg;
105 
106 enum Jobstate
107 {
108     QUEUED,
109     RUNNING,
110     FINISHED,
111     SKIPPED,
112     HOLDING_CLIENT
113 };
114 
115 struct msg
116 {
117     enum msg_types type;
118 
119     union
120     {
121         struct {
122             int command_size;
123             int store_output;
124             int should_keep_finished;
125             int label_size;
126             int env_size;
127             int do_depend;
128             int depend_on; /* -1 means depend on previous */
129             int wait_enqueuing;
130             int num_slots;
131         } newjob;
132         struct {
133             int ofilename_size;
134             int store_output;
135             int pid;
136         } output;
137         int jobid;
138         struct Result {
139             int errorlevel;
140             int died_by_signal;
141             int signal;
142             float user_ms;
143             float system_ms;
144             float real_ms;
145             int skipped;
146         } result;
147         int size;
148         enum Jobstate state;
149         struct {
150             int jobid1;
151             int jobid2;
152         } swap;
153         int last_errorlevel;
154         int max_slots;
155         int version;
156     } u;
157 };
158 
159 struct Procinfo
160 {
161     char *ptr;
162     int nchars;
163     int allocchars;
164     struct timeval enqueue_time;
165     struct timeval start_time;
166     struct timeval end_time;
167 };
168 
169 struct Job
170 {
171     struct Job *next;
172     int jobid;
173     char *command;
174     enum Jobstate state;
175     struct Result result; /* Defined in msg.h */
176     char *output_filename;
177     int store_output;
178     int pid;
179     int should_keep_finished;
180     int do_depend;
181     int depend_on;
182     int *notify_errorlevel_to;
183     int notify_errorlevel_to_size;
184     int dependency_errorlevel;
185     char *label;
186     struct Procinfo info;
187     int num_slots;
188 };
189 
190 enum ExitCodes
191 {
192     EXITCODE_OK            =  0,
193     EXITCODE_UNKNOWN_ERROR = -1,
194     EXITCODE_QUEUE_FULL    = 2
195 };
196 
197 
198 /* client.c */
199 void c_new_job();
200 void c_list_jobs();
201 void c_shutdown_server();
202 void c_wait_server_lines();
203 void c_clear_finished();
204 int c_wait_server_commands();
205 void c_send_runjob_ok(const char *ofname, int pid);
206 int c_tail();
207 int c_cat();
208 void c_show_output_file();
209 void c_remove_job();
210 void c_show_pid();
211 void c_kill_job();
212 int c_wait_job();
213 int c_wait_running_job();
214 int c_wait_job_recv();
215 void c_move_urgent();
216 int c_wait_newjob_ok();
217 void c_get_state();
218 void c_swap_jobs();
219 void c_show_info();
220 char *build_command_string();
221 void c_send_max_slots(int max_slots);
222 void c_get_max_slots();
223 void c_check_version();
224 
225 /* jobs.c */
226 void s_list(int s);
227 int s_newjob(int s, struct msg *m);
228 void s_removejob(int jobid);
229 void job_finished(const struct Result *result, int jobid);
230 int next_run_job();
231 void s_mark_job_running(int jobid);
232 void s_clear_finished();
233 void s_process_runjob_ok(int jobid, char *oname, int pid);
234 void s_send_output(int socket, int jobid);
235 int s_remove_job(int s, int *jobid);
236 void s_remove_notification(int s);
237 void check_notify_list(int jobid);
238 void s_wait_job(int s, int jobid);
239 void s_wait_running_job(int s, int jobid);
240 void s_move_urgent(int s, int jobid);
241 void s_send_state(int s, int jobid);
242 void s_swap_jobs(int s, int jobid1, int jobid2);
243 void dump_jobs_struct(FILE *out);
244 void dump_notifies_struct(FILE *out);
245 void joblist_dump(int fd);
246 const char * jstate2string(enum Jobstate s);
247 void s_job_info(int s, int jobid);
248 void s_send_runjob(int s, int jobid);
249 void s_set_max_slots(int new_max_slots);
250 void s_get_max_slots(int s);
251 int job_is_running(int jobid);
252 int job_is_holding_client(int jobid);
253 int wake_hold_client();
254 
255 /* server.c */
256 void server_main(int notify_fd, char *_path, int ls);
257 void dump_conns_struct(FILE *out);
258 
259 /* server_start.c */
260 int try_connect(int s);
261 void wait_server_up();
262 int ensure_server_up();
263 void notify_parent(int fd);
264 void create_socket_path(char **path);
265 
266 /* execute.c */
267 int run_job();
268 
269 /* client_run.c */
270 void c_run_tail(const char *filename);
271 void c_run_cat(const char *filename);
272 
273 /* mail.c */
274 void send_mail(int jobid, int errorlevel, const char *ofname,
275     const char *command);
276 void hook_on_finish(int jobid, int errorlevel, const char *ofname,
277     const char *command);
278 
279 /* error.c */
280 void error(const char *str, ...);
281 void warning(const char *str, ...);
282 
283 /* signals.c */
284 void ignore_sigpipe();
285 void restore_sigmask();
286 void block_sigint();
287 void unblock_sigint_and_install_handler();
288 
289 /* msg.c */
290 void send_bytes(const int fd, const char *data, int bytes);
291 int recv_bytes(const int fd, char *data, int bytes);
292 void send_msg(const int fd, const struct msg *m);
293 int recv_msg(const int fd, struct msg *m);
294 
295 /* msgdump.c */
296 void msgdump(FILE *, const struct msg *m);
297 
298 /* error.c */
299 void error_msg(const struct msg *m, const char *str, ...);
300 void warning_msg(const struct msg *m, const char *str, ...);
301 
302 /* list.c */
303 char * joblist_headers();
304 char * joblist_line(const struct Job *p);
305 char * joblistdump_torun(const struct Job *p);
306 char * joblistdump_headers();
307 
308 /* print.c */
309 int fd_nprintf(int fd, int maxsize, const char *fmt, ...);
310 
311 /* info.c */
312 
313 void pinfo_dump(const struct Procinfo *p, int fd);
314 void pinfo_addinfo(struct Procinfo *p, int maxsize, const char *line, ...);
315 void pinfo_free(struct Procinfo *p);
316 int pinfo_size(const struct Procinfo *p);
317 void pinfo_set_enqueue_time(struct Procinfo *p);
318 void pinfo_set_start_time(struct Procinfo *p);
319 void pinfo_set_end_time(struct Procinfo *p);
320 float pinfo_time_until_now(const struct Procinfo *p);
321 float pinfo_time_run(const struct Procinfo *p);
322 void pinfo_init(struct Procinfo *p);
323 
324 /* env.c */
325 char * get_environment();
326 
327 /* tail.c */
328 int tail_file(const char *fname, int last_lines);
329