1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
3 * Gui Policy Editor for TOMOYO Linux
6 * Copyright (C) Yoshihiro Kusuno 2010,2011 <yocto@users.sourceforge.jp>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Library General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
28 #include <glib/gi18n.h>
32 #define PRINT_WARN(err) {g_warning("%s", err->message);g_error_free(err);err = NULL;}
34 typedef struct _other_t {
36 GtkActionGroup *actions;
38 generic_list_t manager;
39 generic_list_t memory;
42 static void edit_memory(GtkAction *action, other_t *data);
43 static void append_manager(GtkAction *action, other_t *data);
44 static void delete_manager(GtkAction *action, other_t *data);
46 static GtkActionEntry entries[] = {
47 {"Edit", GTK_STOCK_EDIT, N_("_Edit"), "<control>E",
48 N_("Edit the selected line"), G_CALLBACK(edit_memory)},
49 {"Add", GTK_STOCK_ADD, N_("_Add"), "<control>I",
50 N_("Append line"), G_CALLBACK(append_manager)},
51 {"Delete", GTK_STOCK_DELETE, N_("_Delete"), "<control>D",
52 N_("Delete the selected line"), G_CALLBACK(delete_manager)},
55 static guint n_entries = G_N_ELEMENTS(entries);
57 static const gchar *ui_info =
59 " <toolbar name='ToolBar'>"
60 " <toolitem action='Edit'/>"
61 " <toolitem action='Add'/>"
62 " <toolitem action='Delete'/>"
65 " <popup name='PopUp'>"
66 " <menuitem action='Edit'/>"
67 " <menuitem action='Add'/>"
68 " <menuitem action='Delete'/>"
72 static GtkWidget *create_dialog_menu(GtkWidget *parent, other_t *data)
75 GtkActionGroup *actions;
79 actions = gtk_action_group_new("Actions");
80 gtk_action_group_set_translation_domain(actions, GETTEXT_PACKAGE);
81 gtk_action_group_add_actions(actions, entries, n_entries, data);
83 ui = gtk_ui_manager_new();
84 gtk_ui_manager_insert_action_group(ui, actions, 0);
86 gtk_action_set_sensitive(gtk_action_group_get_action(
87 actions, "Edit"), FALSE);
88 gtk_action_set_sensitive(gtk_action_group_get_action(
89 actions, "Add"), FALSE);
90 gtk_action_set_sensitive(gtk_action_group_get_action(
91 actions, "Delete"), FALSE);
92 data->actions = actions;
94 gtk_window_add_accel_group(GTK_WINDOW(parent),
95 gtk_ui_manager_get_accel_group(ui));
96 if (!gtk_ui_manager_add_ui_from_string(ui, ui_info, -1, NULL)) {
97 g_message("building menus failed: %s", error->message);
101 toolbar = gtk_ui_manager_get_widget(ui, "/ToolBar");
102 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
104 data->popup = gtk_ui_manager_get_widget(ui, "/PopUp");
108 /*-------+---------+---------+---------+---------+---------+---------+--------*/
110 enum list_column_pos {
113 LIST_MANAGER, // display
116 static GtkWidget *create_list_manager(void)
119 GtkListStore *liststore;
120 GtkCellRenderer *renderer;
121 GtkTreeViewColumn *column;
123 liststore = gtk_list_store_new(N_COLUMNS_LIST,
124 G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING);
125 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
126 g_object_unref(liststore);
128 renderer = gtk_cell_renderer_text_new();
129 g_object_set(renderer, "xalign", 1.0, "ypad", 0, NULL);
130 column = gtk_tree_view_column_new_with_attributes(
131 "No.", renderer, "text", LIST_NUMBER, NULL);
132 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
133 gtk_tree_view_column_set_sort_column_id(column, LIST_NUMBER);
135 renderer = gtk_cell_renderer_text_new();
136 column = gtk_tree_view_column_new_with_attributes(" ", renderer,
137 "text", LIST_COLON, NULL);
138 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
140 renderer = gtk_cell_renderer_text_new();
141 column = gtk_tree_view_column_new_with_attributes("operand",
142 renderer, "text", LIST_MANAGER, NULL);
143 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
144 gtk_tree_view_column_set_sort_column_id(column, LIST_MANAGER);
147 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE);
152 static void add_list_manager(generic_list_t *man)
154 GtkTreePath *path = NULL;
155 GtkTreeViewColumn *column = NULL;
160 gtk_tree_view_get_cursor(GTK_TREE_VIEW(
161 man->listview), &path, &column);
163 get_manager(&(man->list), &(man->count));
164 store = GTK_LIST_STORE(gtk_tree_view_get_model(
165 GTK_TREE_VIEW(man->listview)));
167 gtk_list_store_clear(store);
168 for(i = 0; i < man->count; i++){
169 gtk_list_store_append(store, &iter);
170 gtk_list_store_set(store, &iter,
173 LIST_MANAGER, man->list[i].operand,
177 view_cursor_set(man->listview, path, column);
178 gtk_widget_grab_focus(man->listview);
181 static void create_manager_view(GtkWidget *dialog, GtkWidget *listview)
183 GtkWidget *scrolledwin;
185 scrolledwin = gtk_scrolled_window_new(NULL, NULL);
186 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
187 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
188 gtk_scrolled_window_set_shadow_type(
189 GTK_SCROLLED_WINDOW(scrolledwin), GTK_SHADOW_IN);
191 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
192 scrolledwin, TRUE, TRUE, 0);
193 gtk_container_add(GTK_CONTAINER(scrolledwin), listview);
195 view_setting(listview, LIST_MANAGER);
198 static gboolean cb_select_list(GtkTreeView *listview,
199 GdkEventButton *event, other_t *data)
201 if (event->button == 3) {
202 gtk_menu_popup(GTK_MENU(data->popup),
203 NULL, NULL, NULL, NULL,
204 0, gtk_get_current_event_time());
211 /*-------+---------+---------+---------+---------+---------+---------+--------*/
212 static void cb_button(GtkButton *button, gpointer data)
217 static gchar *folder = NULL;
221 parent = GTK_WIDGET(g_object_get_data(G_OBJECT(data), "parent"));
222 entry = GTK_WIDGET(data);
224 dialog = gtk_file_chooser_dialog_new(_("File Selection Dialog"),
226 GTK_FILE_CHOOSER_ACTION_OPEN,
227 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
228 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
231 gtk_file_chooser_set_current_folder(
232 GTK_FILE_CHOOSER(dialog), folder);
235 gtk_widget_show(dialog);
237 response = gtk_dialog_run (GTK_DIALOG(dialog));
238 if (response == GTK_RESPONSE_ACCEPT) {
241 filename = gtk_file_chooser_get_filename(
242 GTK_FILE_CHOOSER(dialog));
243 folder = gtk_file_chooser_get_current_folder(
244 GTK_FILE_CHOOSER(dialog));
245 DEBUG_PRINT("%s\n", folder);
246 gtk_entry_set_text(GTK_ENTRY(entry), filename);
249 DEBUG_PRINT("Another response was recieved.\n");
251 gtk_widget_destroy(dialog);
254 static void append_manager(GtkAction *action, other_t *data)
262 DEBUG_PRINT("append manager\n");
264 dialog = gtk_dialog_new_with_buttons(_("Manager Add"),
265 GTK_WINDOW(data->dialog),
266 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
267 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
268 GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
271 hbox = gtk_hbox_new(FALSE, 5);
273 GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
275 entry = gtk_entry_new();
276 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
277 g_object_set_data(G_OBJECT(entry), "parent", (gpointer)dialog);
279 button = gtk_button_new_from_stock(GTK_STOCK_OPEN);
280 g_signal_connect(G_OBJECT(button), "clicked",
281 G_CALLBACK(cb_button), (gpointer)entry);
282 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
284 gtk_widget_set_size_request(dialog, 600, -1);
285 gtk_widget_show_all(dialog);
287 response = gtk_dialog_run(GTK_DIALOG(dialog));
288 if (response == GTK_RESPONSE_APPLY) {
289 DEBUG_PRINT("append path\n");
291 char *err_buff = NULL;
293 input = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
294 result = add_manager((char *)input, &err_buff);
296 g_warning("%s", err_buff);
299 add_list_manager(&(data->manager));
302 gtk_widget_destroy(dialog);
305 /*-------+---------+---------+---------+---------+---------+---------+--------*/
306 static void set_delete_flag(gpointer data, generic_list_t *gen)
312 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gen->listview));
313 if (!model || !gtk_tree_model_get_iter(model, &iter, data)) {
314 g_warning("ERROR: %s(%d)", __FILE__, __LINE__);
317 gtk_tree_model_get(model, &iter, LIST_NUMBER, &number, -1);
319 DEBUG_PRINT(" index[%d]\n", number);
320 gen->list[number].selected = 1;
323 static void delete_manager(GtkAction *action, other_t *data)
326 GtkTreeSelection *selection;
328 gchar *message = NULL;
330 char *err_buff = NULL;
333 DEBUG_PRINT("delete manager\n");
334 selection = gtk_tree_view_get_selection(
335 GTK_TREE_VIEW(data->manager.listview));
336 if (!selection || !(count =
337 gtk_tree_selection_count_selected_rows(selection)))
340 DEBUG_PRINT("count[%d]\n", count);
341 message = count > 1 ?
342 g_strdup_printf(_("Delete the %d selected managers?"), count) :
343 g_strdup_printf(_("Delete the selected manager?"));
344 dialog = gtk_message_dialog_new(GTK_WINDOW(data->dialog),
345 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
346 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
349 if (GTK_RESPONSE_YES == gtk_dialog_run(GTK_DIALOG(dialog))) {
350 list = gtk_tree_selection_get_selected_rows(selection, NULL);
351 g_list_foreach(list, (GFunc)set_delete_flag, &(data->manager));
352 g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
355 result = delete_manager_policy(data->manager.list,
356 data->manager.count, &err_buff);
358 g_warning("%s", err_buff);
361 add_list_manager(&(data->manager));
364 gtk_widget_destroy(dialog);
367 /*-------+---------+---------+---------+---------+---------+---------+--------*/
368 void manager_main(transition_t *transition)
376 title = disp_window_title(CCS_SCREEN_MANAGER_LIST);
377 dialog = gtk_dialog_new_with_buttons(title,
378 GTK_WINDOW(transition->window),
379 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
380 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
384 create_dialog_menu(dialog, &data);
385 listview = create_list_manager();
386 create_manager_view(dialog, listview);
388 data.dialog = dialog;
389 data.manager.listview = listview;
390 data.manager.count = 0;
391 data.manager.list = NULL;
392 add_list_manager(&(data.manager));
394 gtk_action_set_sensitive(gtk_action_group_get_action(
395 data.actions, "Add"), TRUE);
396 gtk_action_set_sensitive(gtk_action_group_get_action(
397 data.actions, "Delete"), TRUE);
398 g_signal_connect(G_OBJECT(listview), "button-press-event",
399 G_CALLBACK(cb_select_list), &data);
401 gtk_widget_set_size_request(dialog, 640, 480);
402 gtk_widget_set_name(dialog, "GpetManagerDialog"); // .gpetrc
403 gtk_widget_show_all(dialog);
405 response = gtk_dialog_run(GTK_DIALOG(dialog));
406 if (response == GTK_RESPONSE_CLOSE) {
407 DEBUG_PRINT("Close button was pressed.\n");
409 DEBUG_PRINT("Another response was recieved.\n");
411 gtk_widget_destroy(dialog);
413 if (transition->acl_detached &&
414 transition->current_page == CCS_SCREEN_ACL_LIST)
415 transition->current_page = CCS_SCREEN_DOMAIN_LIST;
417 /*-------+---------+---------+---------+---------+---------+---------+--------*/
418 static void get_disp_column(const char *data, gchar **head,
419 gchar **now_str, gchar **quota_str)
422 gchar name[16], date[16], time[16];
424 gboolean bNow = TRUE, bQuota = TRUE;
427 memset(name, 0, sizeof(name));
428 memset(date, 0, sizeof(date));
429 memset(time, 0, sizeof(time));
430 if ((cnt = sscanf(data, "Policy update: %u %s %s %s",
431 &now, name, date, time)) >= 1) {
432 *head = "Policy update";
433 } else if ((cnt = sscanf(data,
434 "Policy violation in learning mode: %u %s %s %s",
435 &now, name, date, time)) >= 1) {
436 *head = "Policy violation in learning mode";
437 } else if ((cnt = sscanf(data,
438 "Policy violation in permissive mode: %u %s %s %s",
439 &now, name, date, time)) >= 1) {
440 *head = "Policy violation in permissive mode";
441 } else if ((cnt = sscanf(data,
442 "Policy violation in enforcing mode: %u %s %s %s",
443 &now, name, date, time)) >= 1) {
444 *head = "Policy violation in enforcing mode";
445 } else if ((cnt = sscanf(data,
446 "Memory used by policy: %u (Quota: %u)",
447 &now, "a)) >= 1) {
448 *head = "Memory used by policy";
449 } else if ((cnt = sscanf(data,
450 "Memory used by audit log: %u (Quota: %u)",
451 &now, "a)) >= 1) {
452 *head = "Memory used by audit log";
453 } else if ((cnt = sscanf(data,
454 "Memory used by query message: %u (Quota: %u)",
455 &now, "a)) >= 1) {
456 *head = "Memory used by query message";
457 } else if ((cnt = sscanf(data,
458 "Total memory used: %u", &now)) == 1) {
459 *head = "Total memory used";
461 *head = (gchar *)data;
464 g_warning("Not found! (Statistics)\n");
469 *now_str = bNow ? g_strdup_printf("%u", now) : g_strdup("");
471 *quota_str = g_strdup_printf("%s %s %s", name, date, time);
473 *quota_str = bQuota ? g_strdup_printf("%u", quota) : g_strdup("");
476 enum mem_column_pos {
483 static void add_list_memory(generic_list_t *mem)
488 gchar *head, *now, *quota;
490 get_memory(&(mem->list), &(mem->count));
491 store = GTK_LIST_STORE(gtk_tree_view_get_model(
492 GTK_TREE_VIEW(mem->listview)));
494 gtk_list_store_clear(store);
495 for(i = 0; i < mem->count; i++){
496 gtk_list_store_append(store, &iter);
497 get_disp_column(mem->list[i].operand,
498 &head, &now, "a);
499 gtk_list_store_set(store, &iter,
508 view_cursor_set(mem->listview, NULL, NULL);
509 gtk_widget_grab_focus(mem->listview);
512 static void cb_cell_edited(GtkCellRendererText *cell,
513 const gchar *path_string, const gchar *new_text,
520 gchar *old_text, *cp, *start;
522 model = gtk_tree_view_get_model(GTK_TREE_VIEW(mem->listview));
523 path = gtk_tree_path_new_from_string(path_string);
524 gtk_tree_model_get_iter(model, &iter, path);
525 gtk_tree_model_get(model, &iter, LIST_QUOTA, &old_text, -1);
527 index = gtk_tree_path_get_indices(path)[0];
528 //(2.16) if (g_strcmp0(old_text, new_text))
529 if (strcmp(old_text, new_text))
530 mem->list[index].selected = 1;
533 start = (gchar *)mem->list[index].operand;
534 cp = strchr(mem->list[index].operand, ':');
537 mem->list[index].operand = g_strdup_printf("%s:%s", start, new_text);
539 DEBUG_PRINT(" Input mem:%2d[%s]\n", index, mem->list[index].operand);
541 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
542 LIST_QUOTA, new_text, -1);
544 gtk_tree_path_free(path);
547 static GtkWidget *create_list_memory(generic_list_t *mem)
550 GtkListStore *liststore;
551 GtkCellRenderer *renderer;
553 liststore = gtk_list_store_new(N_COLUMNS_MEM_LIST,
554 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
555 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
556 g_object_unref(liststore);
558 renderer = gtk_cell_renderer_text_new();
559 gtk_tree_view_insert_column_with_attributes(
560 GTK_TREE_VIEW(treeview), -1, _(" "),
561 renderer, "text", LIST_HEAD, NULL);
562 // gtk_cell_renderer_set_fixed_size(renderer, 250, -1);
564 renderer = gtk_cell_renderer_text_new();
565 g_object_set(renderer, "xalign", 1.0, "ypad", 0, NULL);
566 gtk_tree_view_insert_column_with_attributes(
567 GTK_TREE_VIEW(treeview), -1, _("Now (bytes)"),
568 renderer, "text", LIST_NOW, NULL);
569 gtk_cell_renderer_set_fixed_size(renderer, 100, -1);
571 renderer = gtk_cell_renderer_text_new();
572 g_object_set(renderer, "xalign", 1.0, "ypad", 0, NULL);
573 g_object_set(renderer, "editable", TRUE, NULL);
574 g_signal_connect(renderer, "edited",
575 G_CALLBACK(cb_cell_edited), mem);
576 gtk_tree_view_insert_column_with_attributes(
577 GTK_TREE_VIEW(treeview), -1, _("Quota (bytes)"),
578 renderer, "text", LIST_QUOTA, NULL);
579 // gtk_cell_renderer_set_fixed_size(renderer, 170, -1);
582 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), TRUE);
587 static void create_memory_view(GtkWidget *dialog, GtkWidget *listview)
589 GtkWidget *scrolledwin;
591 scrolledwin = gtk_scrolled_window_new(NULL, NULL);
592 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
593 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
594 gtk_scrolled_window_set_shadow_type(
595 GTK_SCROLLED_WINDOW(scrolledwin), GTK_SHADOW_IN);
597 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
598 scrolledwin, TRUE, TRUE, 0);
599 gtk_container_add(GTK_CONTAINER(scrolledwin), listview);
601 // gtk_tree_view_set_enable_search(GTK_TREE_VIEW(listview), FALSE);
604 static void edit_memory(GtkAction *action, other_t *data)
606 GtkTreeSelection *selection;
608 GtkTreeViewColumn *column;
610 DEBUG_PRINT("edit memory\n");
612 selection = gtk_tree_view_get_selection(
613 GTK_TREE_VIEW(data->memory.listview));
614 list = gtk_tree_selection_get_selected_rows(selection, NULL);
615 column = gtk_tree_view_get_column(
616 GTK_TREE_VIEW(data->memory.listview), LIST_QUOTA);
617 gtk_tree_view_set_cursor_on_cell(
618 GTK_TREE_VIEW(data->memory.listview),
619 g_list_first(list)->data, column, NULL, TRUE);
622 void memory_main(transition_t *transition)
630 title = disp_window_title(CCS_SCREEN_STAT_LIST);
631 dialog = gtk_dialog_new_with_buttons(title,
632 GTK_WINDOW(transition->window),
633 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
634 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
635 GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
639 data.dialog = dialog;
640 data.memory.count = 0;
641 data.memory.list = NULL;
642 create_dialog_menu(dialog, &data);
643 listview = create_list_memory(&(data.memory));
644 data.memory.listview = listview;
645 create_memory_view(dialog, listview);
647 add_list_memory(&(data.memory));
649 gtk_action_set_sensitive(gtk_action_group_get_action(
650 data.actions, "Edit"), TRUE);
651 g_signal_connect(G_OBJECT(listview), "button-press-event",
652 G_CALLBACK(cb_select_list), &data);
654 gtk_widget_set_size_request(dialog, 600, 300);
655 gtk_widget_set_name(dialog, "GpetStatisticsDialog"); // .gpetrc
656 gtk_widget_show_all(dialog);
658 response = gtk_dialog_run(GTK_DIALOG(dialog));
659 if (response == GTK_RESPONSE_APPLY) {
660 char *err_buff = NULL;
661 DEBUG_PRINT("Apply button was pressed.\n");
662 if (set_memory(data.memory.list,
663 data.memory.count, &err_buff)) {
664 g_warning("%s", err_buff);
668 DEBUG_PRINT("Another response was recieved.\n");
670 gtk_widget_destroy(dialog);
672 if (transition->acl_detached &&
673 transition->current_page == CCS_SCREEN_ACL_LIST)
674 transition->current_page = CCS_SCREEN_DOMAIN_LIST;