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 "gtk/common/select.h"
26 #include "auth/credentials/credentials.h"
28 static struct dcerpc_pipe
*at_pipe
= NULL
;
29 static GtkWidget
*mainwin
;
30 static GtkListStore
*store_jobs
;
31 static GtkWidget
*tasks
;
32 static GtkWidget
*new_task
;
33 static GtkWidget
*entry_cmd
;
34 static GtkWidget
*entry_repeat_weekly
;
35 static GtkWidget
*entry_repeat_monthly
;
36 static GtkWidget
*delete;
38 static void update_joblist(void)
40 TALLOC_CTX
*mem_ctx
= talloc_init("update_joblist");
42 struct atsvc_JobEnum r
;
43 struct atsvc_enum_ctr ctr
;
45 uint32_t resume_handle
= 0;
47 gtk_list_store_clear(store_jobs
);
50 ctr
.first_entry
= NULL
;
51 r
.in
.servername
= dcerpc_server_name(at_pipe
);
52 r
.in
.ctr
= r
.out
.ctr
= &ctr
;
53 r
.in
.preferred_max_len
= 0xffffffff;
54 r
.in
.resume_handle
= r
.out
.resume_handle
= &resume_handle
;
56 status
= dcerpc_atsvc_JobEnum(at_pipe
, mem_ctx
, &r
);
57 if(!NT_STATUS_IS_OK(status
)) {
58 gtk_show_ntstatus(mainwin
, "Error while enumerating first job", status
);
62 for (i
= 0; i
< r
.out
.ctr
->entries_read
; i
++) {
64 gtk_list_store_append(store_jobs
, &iter
);
65 gtk_list_store_set (store_jobs
, &iter
,
66 0, r
.out
.ctr
->first_entry
[i
].flags
,
67 1, r
.out
.ctr
->first_entry
[i
].job_id
,
68 2, r
.out
.ctr
->first_entry
[i
].days_of_week
, /*FIXME: Nicer format */
69 3, r
.out
.ctr
->first_entry
[i
].job_time
, /* FIXME: Nicer format */
70 4, r
.out
.ctr
->first_entry
[i
].command
,
77 static void on_job_select(GtkTreeSelection
*sel
, gpointer data
)
79 gtk_widget_set_sensitive(delete, gtk_tree_selection_get_selected(sel
, NULL
, NULL
));
83 static void on_connect_activate(GtkMenuItem
*menuitem
, gpointer user_data
)
85 at_pipe
= gtk_connect_rpc_interface(talloc_autofree_context(), &dcerpc_table_atsvc
);
90 gtk_widget_set_sensitive (new_task
, TRUE
);
94 static void on_quit_activate(GtkMenuItem
*menuitem
, gpointer user_data
)
100 static GtkWidget
* create_new_job_dialog (void);
102 void on_new_activate (GtkMenuItem
*menuitem
, gpointer user_data
)
104 GtkWidget
*d
= create_new_job_dialog();
105 gint result
= gtk_dialog_run(GTK_DIALOG(d
));
106 struct atsvc_JobAdd r
;
107 struct atsvc_JobInfo job
;
111 case GTK_RESPONSE_OK
:
114 gtk_widget_destroy(d
);
117 mem_ctx
= talloc_init("add_job");
119 job
.job_time
= 0; /* FIXME */
120 job
.days_of_month
= 0; /* FIXME */
121 job
.days_of_week
= 0; /* FIXME */
122 job
.flags
= 0; /* FIXME */
123 job
.command
= gtk_entry_get_text(GTK_ENTRY(entry_cmd
));
124 r
.in
.servername
= dcerpc_server_name(at_pipe
);
125 r
.in
.job_info
= &job
;
127 status
= dcerpc_atsvc_JobAdd(at_pipe
, mem_ctx
, &r
);
128 if(!NT_STATUS_IS_OK(status
)) {
129 talloc_free(mem_ctx
);
130 gtk_show_ntstatus(mainwin
, "Error while adding job", status
);
134 talloc_free(mem_ctx
);
135 gtk_widget_destroy(d
);
137 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
);
138 gtk_dialog_run(GTK_DIALOG(d
));
139 gtk_widget_destroy(d
);
144 void on_delete_activate(GtkMenuItem
*menuitem
, gpointer user_data
)
146 GtkTreeSelection
*sel
= gtk_tree_view_get_selection(GTK_TREE_VIEW(tasks
));
147 GtkTreeModel
*model
= GTK_TREE_MODEL(store_jobs
);
151 if (gtk_tree_selection_get_selected (sel
, &model
, &iter
))
153 struct atsvc_JobDel r
;
156 gtk_tree_model_get (model
, &iter
, 1, &id
, -1);
158 r
.in
.servername
= dcerpc_server_name(at_pipe
);
159 r
.in
.min_job_id
= r
.in
.max_job_id
= id
;
161 mem_ctx
= talloc_init("del_job");
162 status
= dcerpc_atsvc_JobDel(at_pipe
, mem_ctx
, &r
);
163 talloc_free(mem_ctx
);
164 if(!NT_STATUS_IS_OK(status
)) {
165 gtk_show_ntstatus(mainwin
, "Error deleting job", status
);
174 static void on_about_activate(GtkMenuItem
*menuitem
, gpointer user_data
)
176 GtkDialog
*aboutwin
= GTK_DIALOG(create_gtk_samba_about_dialog("gwcrontab"));
177 gtk_dialog_run(aboutwin
);
178 gtk_widget_destroy(GTK_WIDGET(aboutwin
));
181 static GtkWidget
* create_mainwindow (void)
183 GtkWidget
*mainwindow
;
186 GtkWidget
*menuitem4
;
187 GtkWidget
*menuitem4_menu
;
188 GtkWidget
*mnu_connect
;
189 GtkWidget
*separatormenuitem1
;
192 GtkWidget
*task_menu
;
193 GtkCellRenderer
*renderer
;
194 GtkTreeViewColumn
*curcol
;
195 GtkWidget
*menuitem7
;
196 GtkWidget
*menuitem7_menu
;
198 GtkWidget
*scrolledwindow
;
199 GtkWidget
*statusbar
;
200 GtkAccelGroup
*accel_group
;
202 accel_group
= gtk_accel_group_new ();
204 mainwindow
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
205 gtk_window_set_default_size (GTK_WINDOW (mainwindow
), 642, 562);
206 gtk_window_set_title (GTK_WINDOW (mainwindow
), "Task Scheduler");
208 vbox
= gtk_vbox_new (FALSE
, 0);
209 gtk_container_add (GTK_CONTAINER (mainwindow
), vbox
);
211 menubar
= gtk_menu_bar_new ();
212 gtk_box_pack_start (GTK_BOX (vbox
), menubar
, FALSE
, FALSE
, 0);
214 menuitem4
= gtk_menu_item_new_with_mnemonic ("_File");
215 gtk_container_add (GTK_CONTAINER (menubar
), menuitem4
);
217 menuitem4_menu
= gtk_menu_new ();
218 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem4
), menuitem4_menu
);
220 mnu_connect
= gtk_menu_item_new_with_mnemonic ("_Connect");
221 gtk_container_add (GTK_CONTAINER (menuitem4_menu
), mnu_connect
);
222 g_signal_connect ((gpointer
) mnu_connect
, "activate",
223 G_CALLBACK (on_connect_activate
), NULL
);
225 separatormenuitem1
= gtk_separator_menu_item_new ();
226 gtk_container_add (GTK_CONTAINER (menuitem4_menu
), separatormenuitem1
);
227 gtk_widget_set_sensitive (separatormenuitem1
, FALSE
);
229 quit
= gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group
);
230 gtk_container_add (GTK_CONTAINER (menuitem4_menu
), quit
);
232 task
= gtk_menu_item_new_with_mnemonic ("_Task");
233 gtk_container_add (GTK_CONTAINER (menubar
), task
);
235 task_menu
= gtk_menu_new ();
236 gtk_menu_item_set_submenu (GTK_MENU_ITEM (task
), task_menu
);
238 new_task
= gtk_menu_item_new_with_mnemonic ("_New");
239 gtk_container_add (GTK_CONTAINER (task_menu
), new_task
);
240 gtk_widget_set_sensitive (new_task
, FALSE
);
242 delete = gtk_menu_item_new_with_mnemonic ("_Delete");
243 gtk_widget_set_sensitive(delete, FALSE
);
244 gtk_container_add (GTK_CONTAINER (task_menu
), delete);
246 menuitem7
= gtk_menu_item_new_with_mnemonic ("_Help");
247 gtk_container_add (GTK_CONTAINER (menubar
), menuitem7
);
249 menuitem7_menu
= gtk_menu_new ();
250 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem7
), menuitem7_menu
);
252 about
= gtk_menu_item_new_with_mnemonic ("_About");
253 gtk_container_add (GTK_CONTAINER (menuitem7_menu
), about
);
255 scrolledwindow
= gtk_scrolled_window_new (NULL
, NULL
);
256 gtk_box_pack_start (GTK_BOX (vbox
), scrolledwindow
, TRUE
, TRUE
, 0);
258 tasks
= gtk_tree_view_new ();
260 curcol
= gtk_tree_view_column_new ();
261 gtk_tree_view_column_set_title(curcol
, "Status");
262 renderer
= gtk_cell_renderer_text_new();
263 gtk_tree_view_column_pack_start(curcol
, renderer
, True
);
264 gtk_tree_view_append_column(GTK_TREE_VIEW(tasks
), curcol
);
265 gtk_tree_view_column_add_attribute(curcol
, renderer
, "text", 0);
267 curcol
= gtk_tree_view_column_new ();
268 gtk_tree_view_column_set_title(curcol
, "ID");
269 renderer
= gtk_cell_renderer_text_new();
270 gtk_tree_view_column_pack_start(curcol
, renderer
, True
);
271 gtk_tree_view_append_column(GTK_TREE_VIEW(tasks
), curcol
);
272 gtk_tree_view_column_add_attribute(curcol
, renderer
, "text", 1);
274 curcol
= gtk_tree_view_column_new ();
275 gtk_tree_view_column_set_title(curcol
, "Day");
276 renderer
= gtk_cell_renderer_text_new();
277 gtk_tree_view_column_pack_start(curcol
, renderer
, True
);
278 gtk_tree_view_append_column(GTK_TREE_VIEW(tasks
), curcol
);
279 gtk_tree_view_column_add_attribute(curcol
, renderer
, "text", 2);
281 curcol
= gtk_tree_view_column_new ();
282 gtk_tree_view_column_set_title(curcol
, "Time");
283 renderer
= gtk_cell_renderer_text_new();
284 gtk_tree_view_column_pack_start(curcol
, renderer
, True
);
285 gtk_tree_view_append_column(GTK_TREE_VIEW(tasks
), curcol
);
286 gtk_tree_view_column_add_attribute(curcol
, renderer
, "text", 3);
288 curcol
= gtk_tree_view_column_new ();
289 gtk_tree_view_column_set_title(curcol
, "Command Line");
290 renderer
= gtk_cell_renderer_text_new();
291 gtk_tree_view_column_pack_start(curcol
, renderer
, True
);
292 gtk_tree_view_append_column(GTK_TREE_VIEW(tasks
), curcol
);
293 gtk_tree_view_column_add_attribute(curcol
, renderer
, "text", 4);
295 store_jobs
= gtk_list_store_new(5, G_TYPE_INT
, G_TYPE_INT
, G_TYPE_INT
, G_TYPE_INT
, G_TYPE_STRING
);
296 gtk_tree_view_set_model(GTK_TREE_VIEW(tasks
), GTK_TREE_MODEL(store_jobs
));
297 g_object_unref(store_jobs
);
299 gtk_container_add (GTK_CONTAINER (scrolledwindow
), tasks
);
301 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(tasks
)) , "changed", G_CALLBACK (on_job_select
), NULL
);
303 statusbar
= gtk_statusbar_new ();
304 gtk_box_pack_start (GTK_BOX (vbox
), statusbar
, FALSE
, FALSE
, 0);
307 g_signal_connect ((gpointer
) quit
, "activate",
308 G_CALLBACK (on_quit_activate
), NULL
);
309 g_signal_connect ((gpointer
) new_task
, "activate",
310 G_CALLBACK (on_new_activate
), NULL
);
311 g_signal_connect ((gpointer
) delete, "activate",
312 G_CALLBACK (on_delete_activate
), NULL
);
313 g_signal_connect ((gpointer
) about
, "activate",
314 G_CALLBACK (on_about_activate
), NULL
);
316 gtk_window_add_accel_group (GTK_WINDOW (mainwindow
), accel_group
);
321 void on_chk_weekly_toggled(GtkToggleButton
*togglebutton
, gpointer user_data
)
323 gtk_widget_set_sensitive(entry_repeat_weekly
, gtk_toggle_button_get_active(togglebutton
));
327 void on_chk_monthly_toggled(GtkToggleButton
*togglebutton
, gpointer user_data
)
329 gtk_widget_set_sensitive(entry_repeat_monthly
, gtk_toggle_button_get_active(togglebutton
));
333 static GtkWidget
*create_new_job_dialog (void)
335 GtkWidget
*new_job_dialog
;
336 GtkWidget
*dialog_vbox1
;
342 GtkWidget
*entry_time
;
343 GtkWidget
*chk_weekly
;
344 GtkWidget
*chk_monthly
;
350 GtkWidget
*dialog_action_area1
;
351 GtkWidget
*cancelbutton1
;
352 GtkWidget
*okbutton1
;
354 new_job_dialog
= gtk_dialog_new ();
355 gtk_window_set_title (GTK_WINDOW (new_job_dialog
), "New job");
357 dialog_vbox1
= GTK_DIALOG (new_job_dialog
)->vbox
;
359 frame1
= gtk_frame_new (NULL
);
360 gtk_box_pack_start (GTK_BOX (dialog_vbox1
), frame1
, TRUE
, TRUE
, 0);
362 table1
= gtk_table_new (4, 2, FALSE
);
363 gtk_container_add (GTK_CONTAINER (frame1
), table1
);
365 label4
= gtk_label_new ("Time:");
366 gtk_table_attach (GTK_TABLE (table1
), label4
, 0, 1, 1, 2,
367 (GtkAttachOptions
) (GTK_FILL
),
368 (GtkAttachOptions
) (0), 0, 0);
369 gtk_misc_set_alignment (GTK_MISC (label4
), 0, 0.5);
371 cal_day
= gtk_calendar_new ();
372 gtk_table_attach (GTK_TABLE (table1
), cal_day
, 1, 2, 0, 1,
373 (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
),
374 (GtkAttachOptions
) (GTK_FILL
), 0, 0);
375 gtk_calendar_set_display_options (GTK_CALENDAR (cal_day
),
376 GTK_CALENDAR_SHOW_HEADING
377 | GTK_CALENDAR_SHOW_DAY_NAMES
);
379 label3
= gtk_label_new ("Date");
380 gtk_table_attach (GTK_TABLE (table1
), label3
, 0, 1, 0, 1,
381 (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
),
382 (GtkAttachOptions
) (0), 0, 0);
383 gtk_misc_set_alignment (GTK_MISC (label3
), 0, 0.5);
385 entry_time
= gtk_entry_new ();
386 gtk_table_attach (GTK_TABLE (table1
), entry_time
, 1, 2, 1, 2,
387 (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
),
388 (GtkAttachOptions
) (0), 0, 0);
390 chk_weekly
= gtk_check_button_new_with_mnemonic ("Repeat weekly");
391 gtk_table_attach (GTK_TABLE (table1
), chk_weekly
, 0, 1, 2, 3,
392 (GtkAttachOptions
) (GTK_FILL
),
393 (GtkAttachOptions
) (0), 0, 0);
395 entry_repeat_weekly
= gtk_entry_new ();
396 gtk_table_attach (GTK_TABLE (table1
), entry_repeat_weekly
, 1, 2, 2, 3,
397 (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
),
398 (GtkAttachOptions
) (0), 0, 0);
400 chk_monthly
= gtk_check_button_new_with_mnemonic ("Repeat monthly");
401 gtk_table_attach (GTK_TABLE (table1
), chk_monthly
, 0, 1, 3, 4,
402 (GtkAttachOptions
) (GTK_FILL
),
403 (GtkAttachOptions
) (0), 0, 0);
405 entry_repeat_monthly
= gtk_entry_new ();
406 gtk_table_attach (GTK_TABLE (table1
), entry_repeat_monthly
, 1, 2, 3, 4,
407 (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
),
408 (GtkAttachOptions
) (0), 0, 0);
410 label1
= gtk_label_new ("Moment");
411 gtk_frame_set_label_widget (GTK_FRAME (frame1
), label1
);
413 frame2
= gtk_frame_new (NULL
);
414 gtk_box_pack_start (GTK_BOX (dialog_vbox1
), frame2
, TRUE
, TRUE
, 0);
416 hbox1
= gtk_hbox_new (FALSE
, 0);
417 gtk_container_add (GTK_CONTAINER (frame2
), hbox1
);
419 label5
= gtk_label_new ("Command to execute");
420 gtk_box_pack_start (GTK_BOX (hbox1
), label5
, TRUE
, TRUE
, 0);
422 entry_cmd
= gtk_entry_new ();
423 gtk_box_pack_start (GTK_BOX (hbox1
), entry_cmd
, TRUE
, TRUE
, 0);
425 label2
= gtk_label_new ("Command");
426 gtk_frame_set_label_widget (GTK_FRAME (frame2
), label2
);
428 dialog_action_area1
= GTK_DIALOG (new_job_dialog
)->action_area
;
429 gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1
), GTK_BUTTONBOX_END
);
431 cancelbutton1
= gtk_button_new_from_stock ("gtk-cancel");
432 gtk_dialog_add_action_widget (GTK_DIALOG (new_job_dialog
), cancelbutton1
, GTK_RESPONSE_CANCEL
);
433 GTK_WIDGET_SET_FLAGS (cancelbutton1
, GTK_CAN_DEFAULT
);
435 okbutton1
= gtk_button_new_from_stock ("gtk-ok");
436 gtk_dialog_add_action_widget (GTK_DIALOG (new_job_dialog
), okbutton1
, GTK_RESPONSE_OK
);
437 GTK_WIDGET_SET_FLAGS (okbutton1
, GTK_CAN_DEFAULT
);
439 g_signal_connect ((gpointer
) chk_weekly
, "toggled",
440 G_CALLBACK (on_chk_weekly_toggled
),
442 g_signal_connect ((gpointer
) chk_monthly
, "toggled",
443 G_CALLBACK (on_chk_monthly_toggled
),
446 return new_job_dialog
;
450 int main(int argc
, char **argv
)
453 setup_logging(argv
[0], DEBUG_STDERR
);
457 gtk_init(&argc
, &argv
);
458 mainwin
= create_mainwindow();
459 gtk_widget_show_all(mainwin
);
461 return gtk_event_loop();