9683570664ab346ecf3e769f6b86a491a240d9ff
[samba.git] / source / gtk / tools / gwcrontab.c
1 /* 
2    Unix SMB/CIFS implementation.
3    GTK+ Windows crontab frontend
4    
5    Copyright (C) Jelmer Vernooij 2004
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #  include <config.h>
24 #endif
25
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <stdio.h>
31
32 #include <gdk/gdkkeysyms.h>
33 #include <gtk/gtk.h>
34 #include "includes.h"
35
36 struct dcerpc_pipe *at_pipe = NULL;
37 GtkWidget *mainwin;
38 GtkListStore *store_jobs;
39 GtkWidget *tasks;
40 GtkWidget *entry_cmd;
41 GtkWidget *entry_repeat_weekly;
42 GtkWidget *entry_repeat_monthly;
43 GtkWidget *delete;
44
45 void update_joblist()
46 {
47         TALLOC_CTX *mem_ctx = talloc_init("update_joblist");
48         NTSTATUS status;
49         struct atsvc_JobEnum r;
50         struct atsvc_enum_ctr ctr;
51         int i;
52         uint32 resume_handle = 0;
53
54         gtk_list_store_clear(store_jobs);
55
56         ctr.entries_read = 0;
57         ctr.first_entry = NULL;
58         r.in.servername = dcerpc_server_name(at_pipe);
59         r.in.ctr = r.out.ctr = &ctr;
60         r.in.preferred_max_len = 0xffffffff;
61         r.in.resume_handle = r.out.resume_handle = &resume_handle;
62         
63         status = dcerpc_atsvc_JobEnum(at_pipe, mem_ctx, &r);
64         if(!NT_STATUS_IS_OK(status)) {
65                 gtk_show_ntstatus(mainwin, status);
66                 return;
67         }
68
69         for (i = 0; r.out.ctr && i < r.out.ctr->entries_read; i++) {
70                 GtkTreeIter iter;
71                 gtk_list_store_append(store_jobs, &iter);
72                 gtk_list_store_set (store_jobs, &iter, 
73                         0, r.out.ctr->first_entry[i].flags,
74                         1, r.out.ctr->first_entry[i].job_id, 
75                         2, r.out.ctr->first_entry[i].days_of_week, /*FIXME: Nicer format */
76                         3, r.out.ctr->first_entry[i].job_time, /* FIXME: Nicer format */
77                         4, r.out.ctr->first_entry[i].command,
78                         -1);
79
80         }
81         talloc_destroy(mem_ctx);
82         gtk_widget_set_sensitive(tasks, TRUE);
83 }
84
85 static void on_job_select(GtkTreeSelection *sel,
86                                              gpointer data)
87 {
88         gtk_widget_set_sensitive(delete, gtk_tree_selection_get_selected(sel, NULL, NULL));
89 }
90
91
92 void
93 on_connect_activate                    (GtkMenuItem     *menuitem,
94                                         gpointer         user_data)
95 {
96         GtkRpcBindingDialog *d;
97         NTSTATUS status;
98         gint result;
99
100         d = GTK_RPC_BINDING_DIALOG(gtk_rpc_binding_dialog_new(FALSE));
101         result = gtk_dialog_run(GTK_DIALOG(d));
102         switch(result) {
103                 case GTK_RESPONSE_ACCEPT:
104                         break;
105                 default: 
106                 gtk_widget_destroy(GTK_WIDGET(d));
107                 return;
108         }
109
110         /* If connected, get list of jobs */
111         status = dcerpc_pipe_connect(&at_pipe, (char *)gtk_rpc_binding_dialog_get_binding(d, DCERPC_ATSVC_NAME), DCERPC_ATSVC_UUID, DCERPC_ATSVC_VERSION, lp_workgroup(), (char *)gtk_rpc_binding_dialog_get_username(d), (char *)gtk_rpc_binding_dialog_get_password(d));
112         if(!NT_STATUS_IS_OK(status)) {
113                 gtk_show_ntstatus(mainwin, status);
114                 at_pipe = NULL;
115                 gtk_widget_destroy(GTK_WIDGET(d));
116                 return;
117         }
118         gtk_widget_destroy(GTK_WIDGET(d));
119
120         update_joblist();
121 }
122
123 void
124 on_quit_activate                      (GtkMenuItem     *menuitem,
125                                         gpointer         user_data)
126 {
127         if(at_pipe)dcerpc_pipe_close(at_pipe);
128         gtk_main_quit();
129 }
130
131
132 static GtkWidget* create_new_job_dialog (void);
133
134 void
135 on_new_activate                        (GtkMenuItem     *menuitem,
136                                         gpointer         user_data)
137 {
138         GtkWidget *d = create_new_job_dialog();
139         gint result = gtk_dialog_run(GTK_DIALOG(d));
140         struct atsvc_JobAdd r;
141         struct atsvc_JobInfo job;
142         NTSTATUS status;
143         TALLOC_CTX *mem_ctx;
144         switch(result) {
145                 case GTK_RESPONSE_OK:
146                         break;
147                 default:
148                         gtk_widget_destroy(d);
149                         return;
150         }
151         mem_ctx = talloc_init("add_job");
152
153         job.job_time = 0; /* FIXME */
154         job.days_of_month = 0; /* FIXME */
155         job.days_of_week = 0; /* FIXME */
156         job.flags = 0; /* FIXME */
157         job.command = gtk_entry_get_text(GTK_ENTRY(entry_cmd));
158         r.in.servername = dcerpc_server_name(at_pipe);
159         r.in.job_info = &job;
160
161         status = dcerpc_atsvc_JobAdd(at_pipe, mem_ctx, &r);
162         if(!NT_STATUS_IS_OK(status)) {
163                 talloc_destroy(mem_ctx);
164                 gtk_show_ntstatus(mainwin, status);
165                 return;
166         }
167         
168         talloc_destroy(mem_ctx);
169         gtk_widget_destroy(d);
170         
171         d = gtk_message_dialog_new (GTK_WINDOW(mainwin), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Job Id: %d", r.out.job_id);
172         gtk_dialog_run(GTK_DIALOG(d));
173         gtk_widget_destroy(d);
174         update_joblist();
175 }
176
177
178 void
179 on_delete_activate                     (GtkMenuItem     *menuitem,
180                                         gpointer         user_data)
181 {
182         GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tasks));
183         GtkTreeModel *model = GTK_TREE_MODEL(store_jobs);
184         GtkTreeIter iter;
185         gint id;
186
187         if (gtk_tree_selection_get_selected (sel, &model, &iter))
188         {
189                 struct atsvc_JobDel r;
190                 TALLOC_CTX *mem_ctx;
191                 NTSTATUS status;
192                 gtk_tree_model_get (model, &iter, 1, &id, -1);
193                 
194                 r.in.servername = dcerpc_server_name(at_pipe);
195                 r.in.min_job_id = r.in.max_job_id = id;
196
197                 mem_ctx = talloc_init("del_job");
198                 status = dcerpc_atsvc_JobDel(at_pipe, mem_ctx, &r);
199                 talloc_destroy(mem_ctx);
200                 if(!NT_STATUS_IS_OK(status)) {
201                         gtk_show_ntstatus(mainwin, status);
202                         return;
203                 }
204         
205                 update_joblist();
206         }
207 }
208
209
210 void
211 on_about_activate                     (GtkMenuItem     *menuitem,
212                                         gpointer         user_data)
213 {
214         GtkDialog *aboutwin = GTK_DIALOG(create_gtk_samba_about_dialog());
215         gtk_dialog_run(aboutwin);
216         gtk_widget_destroy(GTK_WIDGET(aboutwin));
217 }
218
219 GtkWidget*
220 create_mainwindow (void)
221 {
222   GtkWidget *mainwindow;
223   GtkWidget *vbox;
224   GtkWidget *menubar;
225   GtkWidget *menuitem4;
226   GtkWidget *menuitem4_menu;
227   GtkWidget *connect;
228   GtkWidget *separatormenuitem1;
229   GtkWidget *quit;
230   GtkWidget *task;
231   GtkWidget *task_menu;
232   GtkWidget *new;
233   GtkCellRenderer *renderer;
234   GtkTreeViewColumn *curcol;
235   GtkWidget *menuitem7;
236   GtkWidget *menuitem7_menu;
237   GtkWidget *about;
238   GtkWidget *scrolledwindow;
239   GtkWidget *statusbar;
240   GtkAccelGroup *accel_group;
241
242   accel_group = gtk_accel_group_new ();
243
244   mainwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
245   gtk_window_set_title (GTK_WINDOW (mainwindow), "Task Scheduler");
246
247   vbox = gtk_vbox_new (FALSE, 0);
248   gtk_widget_show (vbox);
249   gtk_container_add (GTK_CONTAINER (mainwindow), vbox);
250
251   menubar = gtk_menu_bar_new ();
252   gtk_widget_show (menubar);
253   gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
254
255   menuitem4 = gtk_menu_item_new_with_mnemonic ("_File");
256   gtk_widget_show (menuitem4);
257   gtk_container_add (GTK_CONTAINER (menubar), menuitem4);
258
259   menuitem4_menu = gtk_menu_new ();
260   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem4), menuitem4_menu);
261
262   connect = gtk_menu_item_new_with_mnemonic ("_Connect");
263   gtk_widget_show (connect);
264   gtk_container_add (GTK_CONTAINER (menuitem4_menu), connect);
265
266   separatormenuitem1 = gtk_separator_menu_item_new ();
267   gtk_widget_show (separatormenuitem1);
268   gtk_container_add (GTK_CONTAINER (menuitem4_menu), separatormenuitem1);
269   gtk_widget_set_sensitive (separatormenuitem1, FALSE);
270
271   quit = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group);
272   gtk_widget_show (quit);
273   gtk_container_add (GTK_CONTAINER (menuitem4_menu), quit);
274
275   task = gtk_menu_item_new_with_mnemonic ("_Task");
276   gtk_widget_show (task);
277   gtk_container_add (GTK_CONTAINER (menubar), task);
278
279   task_menu = gtk_menu_new ();
280   gtk_menu_item_set_submenu (GTK_MENU_ITEM (task), task_menu);
281
282   new = gtk_menu_item_new_with_mnemonic ("_New");
283   gtk_widget_show (new);
284   gtk_container_add (GTK_CONTAINER (task_menu), new);
285
286   delete = gtk_menu_item_new_with_mnemonic ("_Delete");
287   gtk_widget_set_sensitive(delete, FALSE);
288   gtk_widget_show (delete);
289   gtk_container_add (GTK_CONTAINER (task_menu), delete);
290
291   menuitem7 = gtk_menu_item_new_with_mnemonic ("_Help");
292   gtk_widget_show (menuitem7);
293   gtk_container_add (GTK_CONTAINER (menubar), menuitem7);
294
295   menuitem7_menu = gtk_menu_new ();
296   gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem7), menuitem7_menu);
297
298   about = gtk_menu_item_new_with_mnemonic ("_About");
299   gtk_widget_show (about);
300   gtk_container_add (GTK_CONTAINER (menuitem7_menu), about);
301
302   scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
303   gtk_widget_show (scrolledwindow);
304   gtk_box_pack_start (GTK_BOX (vbox), scrolledwindow, TRUE, TRUE, 0);
305
306   tasks = gtk_tree_view_new ();
307
308   curcol = gtk_tree_view_column_new ();
309   gtk_tree_view_column_set_title(curcol, "Status");
310   renderer = gtk_cell_renderer_text_new();
311   gtk_tree_view_column_pack_start(curcol, renderer, True);
312   gtk_tree_view_append_column(GTK_TREE_VIEW(tasks), curcol);
313   gtk_tree_view_column_add_attribute(curcol, renderer, "text", 0);
314                                                                                                                              
315   curcol = gtk_tree_view_column_new ();
316   gtk_tree_view_column_set_title(curcol, "ID");
317   renderer = gtk_cell_renderer_text_new();
318   gtk_tree_view_column_pack_start(curcol, renderer, True);
319   gtk_tree_view_append_column(GTK_TREE_VIEW(tasks), curcol);
320   gtk_tree_view_column_add_attribute(curcol, renderer, "text", 1);
321                                                                                                                              
322   curcol = gtk_tree_view_column_new ();
323   gtk_tree_view_column_set_title(curcol, "Day");
324   renderer = gtk_cell_renderer_text_new();
325   gtk_tree_view_column_pack_start(curcol, renderer, True);
326   gtk_tree_view_append_column(GTK_TREE_VIEW(tasks), curcol);
327   gtk_tree_view_column_add_attribute(curcol, renderer, "text", 2);
328
329   curcol = gtk_tree_view_column_new ();
330   gtk_tree_view_column_set_title(curcol, "Time");
331   renderer = gtk_cell_renderer_text_new();
332   gtk_tree_view_column_pack_start(curcol, renderer, True);
333   gtk_tree_view_append_column(GTK_TREE_VIEW(tasks), curcol);
334   gtk_tree_view_column_add_attribute(curcol, renderer, "text", 3);
335
336   curcol = gtk_tree_view_column_new ();
337   gtk_tree_view_column_set_title(curcol, "Command Line");
338   renderer = gtk_cell_renderer_text_new();
339   gtk_tree_view_column_pack_start(curcol, renderer, True);
340   gtk_tree_view_append_column(GTK_TREE_VIEW(tasks), curcol);
341   gtk_tree_view_column_add_attribute(curcol, renderer, "text", 4);
342
343   store_jobs = gtk_list_store_new(5, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING);
344   gtk_tree_view_set_model(GTK_TREE_VIEW(tasks), GTK_TREE_MODEL(store_jobs));
345   g_object_unref(store_jobs);
346
347   gtk_widget_show (tasks);
348   gtk_container_add (GTK_CONTAINER (scrolledwindow), tasks);
349
350   g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(tasks)) , "changed", G_CALLBACK (on_job_select), NULL);
351
352   statusbar = gtk_statusbar_new ();
353   gtk_widget_show (statusbar);
354   gtk_box_pack_start (GTK_BOX (vbox), statusbar, FALSE, FALSE, 0);
355
356   g_signal_connect ((gpointer) connect, "activate",
357                     G_CALLBACK (on_connect_activate),
358                     NULL);
359   g_signal_connect ((gpointer) quit, "activate",
360                     G_CALLBACK (on_quit_activate),
361                     NULL);
362   g_signal_connect ((gpointer) new, "activate",
363                     G_CALLBACK (on_new_activate),
364                     NULL);
365   g_signal_connect ((gpointer) delete, "activate",
366                     G_CALLBACK (on_delete_activate),
367                     NULL);
368   g_signal_connect ((gpointer) about, "activate",
369                     G_CALLBACK (on_about_activate),
370                     NULL);
371
372   gtk_window_add_accel_group (GTK_WINDOW (mainwindow), accel_group);
373   gtk_widget_set_sensitive(tasks, FALSE);
374
375   return mainwindow;
376 }
377
378 void
379 on_chk_weekly_toggled                  (GtkToggleButton *togglebutton,
380                                         gpointer         user_data)
381 {
382         gtk_widget_set_sensitive(entry_repeat_weekly, gtk_toggle_button_get_active(togglebutton));
383 }
384
385
386 void
387 on_chk_monthly_toggled                 (GtkToggleButton *togglebutton,
388                                         gpointer         user_data)
389 {
390         gtk_widget_set_sensitive(entry_repeat_monthly, gtk_toggle_button_get_active(togglebutton));
391 }
392
393
394 static GtkWidget*create_new_job_dialog (void)
395 {
396   GtkWidget *new_job_dialog;
397   GtkWidget *dialog_vbox1;
398   GtkWidget *frame1;
399   GtkWidget *table1;
400   GtkWidget *label4;
401   GtkWidget *cal_day;
402   GtkWidget *label3;
403   GtkWidget *entry_time;
404   GtkWidget *chk_weekly;
405   GtkWidget *chk_monthly;
406   GtkWidget *label1;
407   GtkWidget *frame2;
408   GtkWidget *hbox1;
409   GtkWidget *label5;
410   GtkWidget *label2;
411   GtkWidget *dialog_action_area1;
412   GtkWidget *cancelbutton1;
413   GtkWidget *okbutton1;
414
415   new_job_dialog = gtk_dialog_new ();
416   gtk_window_set_title (GTK_WINDOW (new_job_dialog), "New job");
417
418   dialog_vbox1 = GTK_DIALOG (new_job_dialog)->vbox;
419   gtk_widget_show (dialog_vbox1);
420
421   frame1 = gtk_frame_new (NULL);
422   gtk_widget_show (frame1);
423   gtk_box_pack_start (GTK_BOX (dialog_vbox1), frame1, TRUE, TRUE, 0);
424
425   table1 = gtk_table_new (4, 2, FALSE);
426   gtk_widget_show (table1);
427   gtk_container_add (GTK_CONTAINER (frame1), table1);
428
429   label4 = gtk_label_new ("Time:");
430   gtk_widget_show (label4);
431   gtk_table_attach (GTK_TABLE (table1), label4, 0, 1, 1, 2,
432                     (GtkAttachOptions) (GTK_FILL),
433                     (GtkAttachOptions) (0), 0, 0);
434   gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5);
435
436   cal_day = gtk_calendar_new ();
437   gtk_widget_show (cal_day);
438   gtk_table_attach (GTK_TABLE (table1), cal_day, 1, 2, 0, 1,
439                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
440                     (GtkAttachOptions) (GTK_FILL), 0, 0);
441   gtk_calendar_display_options (GTK_CALENDAR (cal_day),
442                                 GTK_CALENDAR_SHOW_HEADING
443                                 | GTK_CALENDAR_SHOW_DAY_NAMES);
444
445   label3 = gtk_label_new ("Date");
446   gtk_widget_show (label3);
447   gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 0, 1,
448                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
449                     (GtkAttachOptions) (0), 0, 0);
450   gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5);
451
452   entry_time = gtk_entry_new ();
453   gtk_widget_show (entry_time);
454   gtk_table_attach (GTK_TABLE (table1), entry_time, 1, 2, 1, 2,
455                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
456                     (GtkAttachOptions) (0), 0, 0);
457
458   chk_weekly = gtk_check_button_new_with_mnemonic ("Repeat weekly");
459   gtk_widget_show (chk_weekly);
460   gtk_table_attach (GTK_TABLE (table1), chk_weekly, 0, 1, 2, 3,
461                     (GtkAttachOptions) (GTK_FILL),
462                     (GtkAttachOptions) (0), 0, 0);
463
464   entry_repeat_weekly = gtk_entry_new ();
465   gtk_widget_show (entry_repeat_weekly);
466   gtk_table_attach (GTK_TABLE (table1), entry_repeat_weekly, 1, 2, 2, 3,
467                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
468                     (GtkAttachOptions) (0), 0, 0);
469
470   chk_monthly = gtk_check_button_new_with_mnemonic ("Repeat monthly");
471   gtk_widget_show (chk_monthly);
472   gtk_table_attach (GTK_TABLE (table1), chk_monthly, 0, 1, 3, 4,
473                     (GtkAttachOptions) (GTK_FILL),
474                     (GtkAttachOptions) (0), 0, 0);
475
476   entry_repeat_monthly = gtk_entry_new ();
477   gtk_widget_show (entry_repeat_monthly);
478   gtk_table_attach (GTK_TABLE (table1), entry_repeat_monthly, 1, 2, 3, 4,
479                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
480                     (GtkAttachOptions) (0), 0, 0);
481
482   label1 = gtk_label_new ("Moment");
483   gtk_widget_show (label1);
484   gtk_frame_set_label_widget (GTK_FRAME (frame1), label1);
485
486   frame2 = gtk_frame_new (NULL);
487   gtk_widget_show (frame2);
488   gtk_box_pack_start (GTK_BOX (dialog_vbox1), frame2, TRUE, TRUE, 0);
489
490   hbox1 = gtk_hbox_new (FALSE, 0);
491   gtk_widget_show (hbox1);
492   gtk_container_add (GTK_CONTAINER (frame2), hbox1);
493
494   label5 = gtk_label_new ("Command to execute");
495   gtk_widget_show (label5);
496   gtk_box_pack_start (GTK_BOX (hbox1), label5, TRUE, TRUE, 0);
497
498   entry_cmd = gtk_entry_new ();
499   gtk_widget_show (entry_cmd);
500   gtk_box_pack_start (GTK_BOX (hbox1), entry_cmd, TRUE, TRUE, 0);
501
502   label2 = gtk_label_new ("Command");
503   gtk_widget_show (label2);
504   gtk_frame_set_label_widget (GTK_FRAME (frame2), label2);
505
506   dialog_action_area1 = GTK_DIALOG (new_job_dialog)->action_area;
507   gtk_widget_show (dialog_action_area1);
508   gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);
509
510   cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel");
511   gtk_widget_show (cancelbutton1);
512   gtk_dialog_add_action_widget (GTK_DIALOG (new_job_dialog), cancelbutton1, GTK_RESPONSE_CANCEL);
513   GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT);
514
515   okbutton1 = gtk_button_new_from_stock ("gtk-ok");
516   gtk_widget_show (okbutton1);
517   gtk_dialog_add_action_widget (GTK_DIALOG (new_job_dialog), okbutton1, GTK_RESPONSE_OK);
518   GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT);
519
520   g_signal_connect ((gpointer) chk_weekly, "toggled",
521                     G_CALLBACK (on_chk_weekly_toggled),
522                     NULL);
523   g_signal_connect ((gpointer) chk_monthly, "toggled",
524                     G_CALLBACK (on_chk_monthly_toggled),
525                     NULL);
526
527   return new_job_dialog;
528 }
529
530
531
532 int main(int argc, char **argv)
533 {
534         gtk_init(&argc, &argv);
535         mainwin = create_mainwindow();
536         gtk_widget_show(mainwin);
537         gtk_main();
538 }
539