2 Unix SMB/CIFS implementation.
3 GTK+ Windows crontab frontend
5 Copyright (C) Jelmer Vernooij 2004
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.
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.
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.
23 #include "librpc/gen_ndr/ndr_atsvc_c.h"
24 #include "gtk/common/gtk-smb.h"
25 #include "auth/credentials/credentials.h"
27 static struct dcerpc_pipe
*at_pipe
= NULL
;
28 static GtkWidget
*mainwin
;
29 static GtkListStore
*store_jobs
;
30 static GtkWidget
*tasks
;
31 static GtkWidget
*entry_cmd
;
32 static GtkWidget
*entry_repeat_weekly
;
33 static GtkWidget
*entry_repeat_monthly
;
34 static GtkWidget
*delete;
36 static void update_joblist(void)
38 TALLOC_CTX
*mem_ctx
= talloc_init("update_joblist");
40 struct atsvc_JobEnum r
;
41 struct atsvc_enum_ctr ctr
;
43 uint32_t resume_handle
= 0;
45 gtk_list_store_clear(store_jobs
);
48 ctr
.first_entry
= NULL
;
49 r
.in
.servername
= dcerpc_server_name(at_pipe
);
50 r
.in
.ctr
= r
.out
.ctr
= &ctr
;
51 r
.in
.preferred_max_len
= 0xffffffff;
52 r
.in
.resume_handle
= r
.out
.resume_handle
= &resume_handle
;
54 status
= dcerpc_atsvc_JobEnum(at_pipe
, mem_ctx
, &r
);
55 if(!NT_STATUS_IS_OK(status
)) {
56 gtk_show_ntstatus(mainwin
, "Error while enumerating first job", status
);
60 for (i
= 0; r
.out
.ctr
&& i
< r
.out
.ctr
->entries_read
; i
++) {
62 gtk_list_store_append(store_jobs
, &iter
);
63 gtk_list_store_set (store_jobs
, &iter
,
64 0, r
.out
.ctr
->first_entry
[i
].flags
,
65 1, r
.out
.ctr
->first_entry
[i
].job_id
,
66 2, r
.out
.ctr
->first_entry
[i
].days_of_week
, /*FIXME: Nicer format */
67 3, r
.out
.ctr
->first_entry
[i
].job_time
, /* FIXME: Nicer format */
68 4, r
.out
.ctr
->first_entry
[i
].command
,
73 gtk_widget_set_sensitive(tasks
, TRUE
);
76 static void on_job_select(GtkTreeSelection
*sel
, gpointer data
)
78 gtk_widget_set_sensitive(delete, gtk_tree_selection_get_selected(sel
, NULL
, NULL
));
82 static void on_connect_activate(GtkMenuItem
*menuitem
, gpointer user_data
)
84 GtkRpcBindingDialog
*d
;
86 struct cli_credentials
*credentials
;
90 d
= GTK_RPC_BINDING_DIALOG(gtk_rpc_binding_dialog_new(NULL
));
91 result
= gtk_dialog_run(GTK_DIALOG(d
));
93 case GTK_RESPONSE_ACCEPT
:
96 gtk_widget_destroy(GTK_WIDGET(d
));
100 mem_ctx
= talloc_init("gwcrontab_connect");
101 /* If connected, get list of jobs */
103 credentials
= cli_credentials_init(mem_ctx
);
104 cli_credentials_guess(credentials
);
105 cli_credentials_set_gtk_callbacks(credentials
);
107 status
= dcerpc_pipe_connect_b(mem_ctx
, &at_pipe
,
108 gtk_rpc_binding_dialog_get_binding(d
, mem_ctx
),
112 if(!NT_STATUS_IS_OK(status
)) {
113 gtk_show_ntstatus(mainwin
, "Error while connecting to at service", status
);
115 gtk_widget_destroy(GTK_WIDGET(d
));
116 talloc_free(mem_ctx
);
119 gtk_widget_destroy(GTK_WIDGET(d
));
121 at_pipe
= talloc_reference(talloc_autofree_context(), at_pipe
);
122 talloc_free(mem_ctx
);
126 static void on_quit_activate(GtkMenuItem
*menuitem
, gpointer user_data
)
128 talloc_free(at_pipe
);
133 static GtkWidget
* create_new_job_dialog (void);
136 on_new_activate (GtkMenuItem
*menuitem
,
139 GtkWidget
*d
= create_new_job_dialog();
140 gint result
= gtk_dialog_run(GTK_DIALOG(d
));
141 struct atsvc_JobAdd r
;
142 struct atsvc_JobInfo job
;
146 case GTK_RESPONSE_OK
:
149 gtk_widget_destroy(d
);
152 mem_ctx
= talloc_init("add_job");
154 job
.job_time
= 0; /* FIXME */
155 job
.days_of_month
= 0; /* FIXME */
156 job
.days_of_week
= 0; /* FIXME */
157 job
.flags
= 0; /* FIXME */
158 job
.command
= gtk_entry_get_text(GTK_ENTRY(entry_cmd
));
159 r
.in
.servername
= dcerpc_server_name(at_pipe
);
160 r
.in
.job_info
= &job
;
162 status
= dcerpc_atsvc_JobAdd(at_pipe
, mem_ctx
, &r
);
163 if(!NT_STATUS_IS_OK(status
)) {
164 talloc_free(mem_ctx
);
165 gtk_show_ntstatus(mainwin
, "Error while adding job", status
);
169 talloc_free(mem_ctx
);
170 gtk_widget_destroy(d
);
172 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
);
173 gtk_dialog_run(GTK_DIALOG(d
));
174 gtk_widget_destroy(d
);
180 on_delete_activate (GtkMenuItem
*menuitem
,
183 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tasks
));
184 GtkTreeModel
*model
= GTK_TREE_MODEL(store_jobs
);
188 if (gtk_tree_selection_get_selected (sel
, &model
, &iter
))
190 struct atsvc_JobDel r
;
193 gtk_tree_model_get (model
, &iter
, 1, &id
, -1);
195 r
.in
.servername
= dcerpc_server_name(at_pipe
);
196 r
.in
.min_job_id
= r
.in
.max_job_id
= id
;
198 mem_ctx
= talloc_init("del_job");
199 status
= dcerpc_atsvc_JobDel(at_pipe
, mem_ctx
, &r
);
200 talloc_free(mem_ctx
);
201 if(!NT_STATUS_IS_OK(status
)) {
202 gtk_show_ntstatus(mainwin
, "Error deleting job", status
);
211 static void on_about_activate(GtkMenuItem
*menuitem
, gpointer user_data
)
213 GtkDialog
*aboutwin
= GTK_DIALOG(create_gtk_samba_about_dialog("gwcrontab"));
214 gtk_dialog_run(aboutwin
);
215 gtk_widget_destroy(GTK_WIDGET(aboutwin
));
218 static GtkWidget
* create_mainwindow (void)
220 GtkWidget
*mainwindow
;
223 GtkWidget
*menuitem4
;
224 GtkWidget
*menuitem4_menu
;
225 GtkWidget
*mnu_connect
;
226 GtkWidget
*separatormenuitem1
;
229 GtkWidget
*task_menu
;
231 GtkCellRenderer
*renderer
;
232 GtkTreeViewColumn
*curcol
;
233 GtkWidget
*menuitem7
;
234 GtkWidget
*menuitem7_menu
;
236 GtkWidget
*scrolledwindow
;
237 GtkWidget
*statusbar
;
238 GtkAccelGroup
*accel_group
;
240 accel_group
= gtk_accel_group_new ();
242 mainwindow
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
243 gtk_window_set_default_size (GTK_WINDOW (mainwindow
), 642, 562);
244 gtk_window_set_title (GTK_WINDOW (mainwindow
), "Task Scheduler");
246 vbox
= gtk_vbox_new (FALSE
, 0);
247 gtk_container_add (GTK_CONTAINER (mainwindow
), vbox
);
249 menubar
= gtk_menu_bar_new ();
250 gtk_box_pack_start (GTK_BOX (vbox
), menubar
, FALSE
, FALSE
, 0);
252 menuitem4
= gtk_menu_item_new_with_mnemonic ("_File");
253 gtk_container_add (GTK_CONTAINER (menubar
), menuitem4
);
255 menuitem4_menu
= gtk_menu_new ();
256 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem4
), menuitem4_menu
);
258 mnu_connect
= gtk_menu_item_new_with_mnemonic ("_Connect");
259 gtk_container_add (GTK_CONTAINER (menuitem4_menu
), mnu_connect
);
260 g_signal_connect ((gpointer
) mnu_connect
, "activate",
261 G_CALLBACK (on_connect_activate
), NULL
);
263 separatormenuitem1
= gtk_separator_menu_item_new ();
264 gtk_container_add (GTK_CONTAINER (menuitem4_menu
), separatormenuitem1
);
265 gtk_widget_set_sensitive (separatormenuitem1
, FALSE
);
267 quit
= gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group
);
268 gtk_container_add (GTK_CONTAINER (menuitem4_menu
), quit
);
270 task
= gtk_menu_item_new_with_mnemonic ("_Task");
271 gtk_container_add (GTK_CONTAINER (menubar
), task
);
273 task_menu
= gtk_menu_new ();
274 gtk_menu_item_set_submenu (GTK_MENU_ITEM (task
), task_menu
);
276 new = gtk_menu_item_new_with_mnemonic ("_New");
277 gtk_container_add (GTK_CONTAINER (task_menu
), new);
279 delete = gtk_menu_item_new_with_mnemonic ("_Delete");
280 gtk_widget_set_sensitive(delete, FALSE
);
281 gtk_container_add (GTK_CONTAINER (task_menu
), delete);
283 menuitem7
= gtk_menu_item_new_with_mnemonic ("_Help");
284 gtk_container_add (GTK_CONTAINER (menubar
), menuitem7
);
286 menuitem7_menu
= gtk_menu_new ();
287 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem7
), menuitem7_menu
);
289 about
= gtk_menu_item_new_with_mnemonic ("_About");
290 gtk_container_add (GTK_CONTAINER (menuitem7_menu
), about
);
292 scrolledwindow
= gtk_scrolled_window_new (NULL
, NULL
);
293 gtk_box_pack_start (GTK_BOX (vbox
), scrolledwindow
, TRUE
, TRUE
, 0);
295 tasks
= gtk_tree_view_new ();
297 curcol
= gtk_tree_view_column_new ();
298 gtk_tree_view_column_set_title(curcol
, "Status");
299 renderer
= gtk_cell_renderer_text_new();
300 gtk_tree_view_column_pack_start(curcol
, renderer
, True
);
301 gtk_tree_view_append_column(GTK_TREE_VIEW(tasks
), curcol
);
302 gtk_tree_view_column_add_attribute(curcol
, renderer
, "text", 0);
304 curcol
= gtk_tree_view_column_new ();
305 gtk_tree_view_column_set_title(curcol
, "ID");
306 renderer
= gtk_cell_renderer_text_new();
307 gtk_tree_view_column_pack_start(curcol
, renderer
, True
);
308 gtk_tree_view_append_column(GTK_TREE_VIEW(tasks
), curcol
);
309 gtk_tree_view_column_add_attribute(curcol
, renderer
, "text", 1);
311 curcol
= gtk_tree_view_column_new ();
312 gtk_tree_view_column_set_title(curcol
, "Day");
313 renderer
= gtk_cell_renderer_text_new();
314 gtk_tree_view_column_pack_start(curcol
, renderer
, True
);
315 gtk_tree_view_append_column(GTK_TREE_VIEW(tasks
), curcol
);
316 gtk_tree_view_column_add_attribute(curcol
, renderer
, "text", 2);
318 curcol
= gtk_tree_view_column_new ();
319 gtk_tree_view_column_set_title(curcol
, "Time");
320 renderer
= gtk_cell_renderer_text_new();
321 gtk_tree_view_column_pack_start(curcol
, renderer
, True
);
322 gtk_tree_view_append_column(GTK_TREE_VIEW(tasks
), curcol
);
323 gtk_tree_view_column_add_attribute(curcol
, renderer
, "text", 3);
325 curcol
= gtk_tree_view_column_new ();
326 gtk_tree_view_column_set_title(curcol
, "Command Line");
327 renderer
= gtk_cell_renderer_text_new();
328 gtk_tree_view_column_pack_start(curcol
, renderer
, True
);
329 gtk_tree_view_append_column(GTK_TREE_VIEW(tasks
), curcol
);
330 gtk_tree_view_column_add_attribute(curcol
, renderer
, "text", 4);
332 store_jobs
= gtk_list_store_new(5, G_TYPE_INT
, G_TYPE_INT
, G_TYPE_INT
, G_TYPE_INT
, G_TYPE_STRING
);
333 gtk_tree_view_set_model(GTK_TREE_VIEW(tasks
), GTK_TREE_MODEL(store_jobs
));
334 g_object_unref(store_jobs
);
336 gtk_container_add (GTK_CONTAINER (scrolledwindow
), tasks
);
338 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(tasks
)) , "changed", G_CALLBACK (on_job_select
), NULL
);
340 statusbar
= gtk_statusbar_new ();
341 gtk_box_pack_start (GTK_BOX (vbox
), statusbar
, FALSE
, FALSE
, 0);
344 g_signal_connect ((gpointer
) quit
, "activate",
345 G_CALLBACK (on_quit_activate
), NULL
);
346 g_signal_connect ((gpointer
) new, "activate",
347 G_CALLBACK (on_new_activate
), NULL
);
348 g_signal_connect ((gpointer
) delete, "activate",
349 G_CALLBACK (on_delete_activate
), NULL
);
350 g_signal_connect ((gpointer
) about
, "activate",
351 G_CALLBACK (on_about_activate
), NULL
);
353 gtk_window_add_accel_group (GTK_WINDOW (mainwindow
), accel_group
);
354 gtk_widget_set_sensitive(tasks
, FALSE
);
360 on_chk_weekly_toggled (GtkToggleButton
*togglebutton
,
363 gtk_widget_set_sensitive(entry_repeat_weekly
, gtk_toggle_button_get_active(togglebutton
));
368 on_chk_monthly_toggled (GtkToggleButton
*togglebutton
,
371 gtk_widget_set_sensitive(entry_repeat_monthly
, gtk_toggle_button_get_active(togglebutton
));
375 static GtkWidget
*create_new_job_dialog (void)
377 GtkWidget
*new_job_dialog
;
378 GtkWidget
*dialog_vbox1
;
384 GtkWidget
*entry_time
;
385 GtkWidget
*chk_weekly
;
386 GtkWidget
*chk_monthly
;
392 GtkWidget
*dialog_action_area1
;
393 GtkWidget
*cancelbutton1
;
394 GtkWidget
*okbutton1
;
396 new_job_dialog
= gtk_dialog_new ();
397 gtk_window_set_title (GTK_WINDOW (new_job_dialog
), "New job");
399 dialog_vbox1
= GTK_DIALOG (new_job_dialog
)->vbox
;
401 frame1
= gtk_frame_new (NULL
);
402 gtk_box_pack_start (GTK_BOX (dialog_vbox1
), frame1
, TRUE
, TRUE
, 0);
404 table1
= gtk_table_new (4, 2, FALSE
);
405 gtk_container_add (GTK_CONTAINER (frame1
), table1
);
407 label4
= gtk_label_new ("Time:");
408 gtk_table_attach (GTK_TABLE (table1
), label4
, 0, 1, 1, 2,
409 (GtkAttachOptions
) (GTK_FILL
),
410 (GtkAttachOptions
) (0), 0, 0);
411 gtk_misc_set_alignment (GTK_MISC (label4
), 0, 0.5);
413 cal_day
= gtk_calendar_new ();
414 gtk_table_attach (GTK_TABLE (table1
), cal_day
, 1, 2, 0, 1,
415 (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
),
416 (GtkAttachOptions
) (GTK_FILL
), 0, 0);
417 gtk_calendar_set_display_options (GTK_CALENDAR (cal_day
),
418 GTK_CALENDAR_SHOW_HEADING
419 | GTK_CALENDAR_SHOW_DAY_NAMES
);
421 label3
= gtk_label_new ("Date");
422 gtk_table_attach (GTK_TABLE (table1
), label3
, 0, 1, 0, 1,
423 (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
),
424 (GtkAttachOptions
) (0), 0, 0);
425 gtk_misc_set_alignment (GTK_MISC (label3
), 0, 0.5);
427 entry_time
= gtk_entry_new ();
428 gtk_table_attach (GTK_TABLE (table1
), entry_time
, 1, 2, 1, 2,
429 (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
),
430 (GtkAttachOptions
) (0), 0, 0);
432 chk_weekly
= gtk_check_button_new_with_mnemonic ("Repeat weekly");
433 gtk_table_attach (GTK_TABLE (table1
), chk_weekly
, 0, 1, 2, 3,
434 (GtkAttachOptions
) (GTK_FILL
),
435 (GtkAttachOptions
) (0), 0, 0);
437 entry_repeat_weekly
= gtk_entry_new ();
438 gtk_table_attach (GTK_TABLE (table1
), entry_repeat_weekly
, 1, 2, 2, 3,
439 (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
),
440 (GtkAttachOptions
) (0), 0, 0);
442 chk_monthly
= gtk_check_button_new_with_mnemonic ("Repeat monthly");
443 gtk_table_attach (GTK_TABLE (table1
), chk_monthly
, 0, 1, 3, 4,
444 (GtkAttachOptions
) (GTK_FILL
),
445 (GtkAttachOptions
) (0), 0, 0);
447 entry_repeat_monthly
= gtk_entry_new ();
448 gtk_table_attach (GTK_TABLE (table1
), entry_repeat_monthly
, 1, 2, 3, 4,
449 (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
),
450 (GtkAttachOptions
) (0), 0, 0);
452 label1
= gtk_label_new ("Moment");
453 gtk_frame_set_label_widget (GTK_FRAME (frame1
), label1
);
455 frame2
= gtk_frame_new (NULL
);
456 gtk_box_pack_start (GTK_BOX (dialog_vbox1
), frame2
, TRUE
, TRUE
, 0);
458 hbox1
= gtk_hbox_new (FALSE
, 0);
459 gtk_container_add (GTK_CONTAINER (frame2
), hbox1
);
461 label5
= gtk_label_new ("Command to execute");
462 gtk_box_pack_start (GTK_BOX (hbox1
), label5
, TRUE
, TRUE
, 0);
464 entry_cmd
= gtk_entry_new ();
465 gtk_box_pack_start (GTK_BOX (hbox1
), entry_cmd
, TRUE
, TRUE
, 0);
467 label2
= gtk_label_new ("Command");
468 gtk_frame_set_label_widget (GTK_FRAME (frame2
), label2
);
470 dialog_action_area1
= GTK_DIALOG (new_job_dialog
)->action_area
;
471 gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1
), GTK_BUTTONBOX_END
);
473 cancelbutton1
= gtk_button_new_from_stock ("gtk-cancel");
474 gtk_dialog_add_action_widget (GTK_DIALOG (new_job_dialog
), cancelbutton1
, GTK_RESPONSE_CANCEL
);
475 GTK_WIDGET_SET_FLAGS (cancelbutton1
, GTK_CAN_DEFAULT
);
477 okbutton1
= gtk_button_new_from_stock ("gtk-ok");
478 gtk_dialog_add_action_widget (GTK_DIALOG (new_job_dialog
), okbutton1
, GTK_RESPONSE_OK
);
479 GTK_WIDGET_SET_FLAGS (okbutton1
, GTK_CAN_DEFAULT
);
481 g_signal_connect ((gpointer
) chk_weekly
, "toggled",
482 G_CALLBACK (on_chk_weekly_toggled
),
484 g_signal_connect ((gpointer
) chk_monthly
, "toggled",
485 G_CALLBACK (on_chk_monthly_toggled
),
488 return new_job_dialog
;
492 int main(int argc
, char **argv
)
496 setup_logging(argv
[0], DEBUG_STDERR
);
498 gtk_init(&argc
, &argv
);
499 mainwin
= create_mainwindow();
500 gtk_widget_show_all(mainwin
);
502 return gtk_event_loop();