79 |
79 |
#define FREE_FILL_B 0.811764706 |
80 |
80 |
|
81 |
81 |
|
|
82 |
#ifdef HAVE_SELINUX |
|
83 |
# include <selinux/selinux.h> |
|
84 |
#endif |
|
85 |
|
82 |
86 |
#define PREVIEW_IMAGE_WIDTH 96 |
83 |
87 |
|
84 |
88 |
#define ROW_PAD 6 |
… |
118 |
122 |
unsigned int owner_change_timeout; |
119 |
123 |
|
120 |
124 |
GList *permission_buttons; |
121 |
|
GList *permission_combos; |
|
125 |
GList *permission_combos; /* how is this deallocated???? */ |
|
126 |
GList *selinux_combo; |
122 |
127 |
GHashTable *initial_permissions; |
123 |
128 |
gboolean has_recursive_apply; |
124 |
129 |
|
125 |
130 |
GList *value_fields; |
126 |
131 |
|
|
132 |
GList *edit_fields; |
|
133 |
|
127 |
134 |
GList *mime_list; |
128 |
135 |
|
129 |
136 |
gboolean deep_count_finished; |
… |
206 |
213 |
GtkComboBox *combo); |
207 |
214 |
static void value_field_update (NautilusPropertiesWindow *window, |
208 |
215 |
GtkLabel *field); |
|
216 |
static void edit_field_update (NautilusPropertiesWindow *window, |
|
217 |
GtkEntry *field); |
|
218 |
static void popup_field_update (NautilusPropertiesWindow *window, |
|
219 |
GtkComboBox *entry); |
209 |
220 |
static void properties_window_update (NautilusPropertiesWindow *window, |
210 |
221 |
GList *files); |
211 |
222 |
static void is_directory_ready_callback (NautilusFile *file, |
… |
235 |
246 |
const char *initial_text); |
236 |
247 |
|
237 |
248 |
static GtkWidget* create_pie_widget (NautilusPropertiesWindow *window); |
|
249 |
|
|
250 |
static void attach_selinux_data_edit_field (GtkEntry *entry, |
|
251 |
char *attr_value, |
|
252 |
char *def_attr_value); |
|
253 |
|
|
254 |
#ifdef HAVE_SELINUX |
|
255 |
static void attach_selinux_data_popup_field (GtkComboBox *comb, |
|
256 |
char *attr_val, |
|
257 |
char *def_attr_val); |
|
258 |
#endif |
238 |
259 |
|
239 |
260 |
G_DEFINE_TYPE (NautilusPropertiesWindow, nautilus_properties_window, GTK_TYPE_DIALOG); |
240 |
261 |
#define parent_class nautilus_properties_window_parent_class |
241 |
262 |
|
|
263 |
static void |
|
264 |
maybe_gtk_entry_set_text (GtkEntry *entry, const char *val) |
|
265 |
{ |
|
266 |
char *old_val; |
|
267 |
|
|
268 |
g_assert (GTK_IS_ENTRY (entry)); |
|
269 |
|
|
270 |
old_val = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1); |
|
271 |
|
|
272 |
if (strcmp (old_val, val) != 0) { |
|
273 |
gtk_entry_set_text (entry, val); |
|
274 |
} |
|
275 |
g_free(old_val); |
|
276 |
} |
|
277 |
|
242 |
278 |
static gboolean |
243 |
279 |
is_multi_file_window (NautilusPropertiesWindow *window) |
244 |
280 |
{ |
… |
259 |
295 |
return FALSE; |
260 |
296 |
} |
261 |
297 |
|
|
298 |
static gboolean |
|
299 |
all_can_get_permissions (GList *file_list) |
|
300 |
{ |
|
301 |
GList *l; |
|
302 |
for (l = file_list; l != NULL; l = l->next) { |
|
303 |
NautilusFile *file; |
|
304 |
|
|
305 |
file = NAUTILUS_FILE (l->data); |
|
306 |
|
|
307 |
if (!nautilus_file_can_get_permissions (file)) { |
|
308 |
return FALSE; |
|
309 |
} |
|
310 |
} |
|
311 |
|
|
312 |
return TRUE; |
|
313 |
} |
|
314 |
|
|
315 |
static gboolean |
|
316 |
all_can_set_permissions (GList *file_list) |
|
317 |
{ |
|
318 |
GList *l; |
|
319 |
for (l = file_list; l != NULL; l = l->next) { |
|
320 |
NautilusFile *file; |
|
321 |
|
|
322 |
file = NAUTILUS_FILE (l->data); |
|
323 |
|
|
324 |
if (!nautilus_file_can_set_permissions (file)) { |
|
325 |
return FALSE; |
|
326 |
} |
|
327 |
} |
|
328 |
|
|
329 |
return TRUE; |
|
330 |
} |
|
331 |
|
|
332 |
#ifdef HAVE_SELINUX |
|
333 |
static gboolean |
|
334 |
multi_have_same_selinux_context (NautilusPropertiesWindow *window) |
|
335 |
{ |
|
336 |
GList *l; |
|
337 |
char *cntx; |
|
338 |
|
|
339 |
cntx = NULL; |
|
340 |
for (l = window->details->original_files; l != NULL; l = l->next) { |
|
341 |
NautilusFile *file; |
|
342 |
|
|
343 |
file = NAUTILUS_FILE (l->data); |
|
344 |
if (!nautilus_file_is_gone (file)) { |
|
345 |
char *tmp; |
|
346 |
|
|
347 |
tmp = nautilus_file_get_string_attribute_with_default (file, "selinux_context"); |
|
348 |
if (!cntx) { |
|
349 |
cntx = tmp; |
|
350 |
} else if (strcmp (cntx, tmp)) { |
|
351 |
g_free (tmp); |
|
352 |
g_free (cntx); |
|
353 |
return FALSE; |
|
354 |
} |
|
355 |
else { |
|
356 |
g_free (tmp); |
|
357 |
} |
|
358 |
} |
|
359 |
} |
|
360 |
|
|
361 |
g_free (cntx); |
|
362 |
|
|
363 |
return TRUE; |
|
364 |
} |
|
365 |
#endif |
|
366 |
|
|
367 |
/* NOTE: This modifies cntx */ |
|
368 |
static void |
|
369 |
selinux_split_cntx (char *cntx, |
|
370 |
const char **ret_attr_u, |
|
371 |
const char **ret_attr_r, |
|
372 |
const char **ret_attr_t, |
|
373 |
const char **ret_attr_s) |
|
374 |
{ |
|
375 |
const char *attr_u; |
|
376 |
const char *attr_r; |
|
377 |
const char *attr_t; |
|
378 |
const char *attr_s; |
|
379 |
|
|
380 |
attr_u = cntx; |
|
381 |
if (!(attr_r = strchr (attr_u, ':'))) { |
|
382 |
attr_r = "object_r"; /* shouldn't happen */ |
|
383 |
} else { |
|
384 |
*((char *)attr_r++) = 0; |
|
385 |
} |
|
386 |
|
|
387 |
if (!(attr_t = strchr (attr_r, ':'))) { |
|
388 |
attr_t = "file_t"; /* shouldn't happen */ |
|
389 |
} else { |
|
390 |
*((char *)attr_t++) = 0; |
|
391 |
} |
|
392 |
|
|
393 |
if ((attr_s = strchr (attr_t, ':'))) { |
|
394 |
*((char *)attr_s++) = 0; |
|
395 |
} |
|
396 |
|
|
397 |
*ret_attr_u = attr_u; |
|
398 |
*ret_attr_r = attr_r; |
|
399 |
*ret_attr_t = attr_t; |
|
400 |
*ret_attr_s = attr_s; |
|
401 |
} |
|
402 |
|
262 |
403 |
static int |
263 |
404 |
get_not_gone_original_file_count (NautilusPropertiesWindow *window) |
264 |
405 |
{ |
… |
634 |
775 |
* currently showing. This causes minimal ripples (e.g. |
635 |
776 |
* selection change). |
636 |
777 |
*/ |
637 |
|
gchar *displayed_name = gtk_editable_get_chars (GTK_EDITABLE (window->details->name_field), 0, -1); |
638 |
|
if (strcmp (displayed_name, name) != 0) { |
639 |
|
gtk_entry_set_text (GTK_ENTRY (window->details->name_field), name); |
640 |
|
} |
641 |
|
g_free (displayed_name); |
|
778 |
maybe_gtk_entry_set_text (GTK_ENTRY (window->details->name_field), name); |
642 |
779 |
} |
643 |
780 |
} |
644 |
781 |
} |
… |
718 |
855 |
name_field_restore_original_name (NautilusEntry *name_field) |
719 |
856 |
{ |
720 |
857 |
const char *original_name; |
721 |
|
char *displayed_name; |
722 |
858 |
|
723 |
859 |
original_name = (const char *) g_object_get_data (G_OBJECT (name_field), |
724 |
860 |
"original_name"); |
… |
727 |
863 |
return; |
728 |
864 |
} |
729 |
865 |
|
730 |
|
displayed_name = gtk_editable_get_chars (GTK_EDITABLE (name_field), 0, -1); |
731 |
|
|
732 |
|
if (strcmp (original_name, displayed_name) != 0) { |
733 |
|
gtk_entry_set_text (GTK_ENTRY (name_field), original_name); |
734 |
|
} |
|
866 |
maybe_gtk_entry_set_text (GTK_ENTRY (name_field), original_name); |
735 |
867 |
nautilus_entry_select_all (name_field); |
736 |
|
|
737 |
|
g_free (displayed_name); |
738 |
868 |
} |
739 |
869 |
|
740 |
870 |
static void |
… |
1028 |
1158 |
for (l = window->details->value_fields; l != NULL; l = l->next) { |
1029 |
1159 |
value_field_update (window, GTK_LABEL (l->data)); |
1030 |
1160 |
} |
|
1161 |
|
|
1162 |
for (l = window->details->edit_fields; l != NULL; l = l->next) { |
|
1163 |
edit_field_update (window, GTK_ENTRY (l->data)); |
|
1164 |
} |
|
1165 |
|
|
1166 |
for (l = window->details->selinux_combo; l != NULL; l = l->next) { |
|
1167 |
popup_field_update (window, GTK_COMBO_BOX (l->data)); |
|
1168 |
} |
1031 |
1169 |
} |
1032 |
1170 |
|
1033 |
1171 |
mime_list = get_mime_list (window); |
… |
1198 |
1336 |
window->details->target_files)); |
1199 |
1337 |
} |
1200 |
1338 |
|
|
1339 |
static void |
|
1340 |
edit_field_update_internal (GtkEntry *entry, |
|
1341 |
GList *file_list) |
|
1342 |
{ |
|
1343 |
const char *attr_name; |
|
1344 |
char *attr_value; |
|
1345 |
char *def_attr_value; |
|
1346 |
char *inconsistent_string; |
|
1347 |
gboolean sensitive; |
|
1348 |
|
|
1349 |
g_assert (GTK_IS_ENTRY (entry)); |
|
1350 |
|
|
1351 |
attr_name = g_object_get_data (G_OBJECT (entry), "file_attribute"); |
|
1352 |
inconsistent_string = g_object_get_data (G_OBJECT (entry), |
|
1353 |
"inconsistent_string"); |
|
1354 |
def_attr_value = g_object_get_data (G_OBJECT (entry), |
|
1355 |
"matchpathcon_cntx"); |
|
1356 |
|
|
1357 |
attr_value = file_list_get_string_attribute (file_list, attr_name, |
|
1358 |
inconsistent_string); |
|
1359 |
|
|
1360 |
maybe_gtk_entry_set_text (GTK_ENTRY (entry), attr_value); |
|
1361 |
|
|
1362 |
/* JFIXME: this isn't generic, *sigh* ... */ |
|
1363 |
attach_selinux_data_edit_field (entry, attr_value, def_attr_value); |
|
1364 |
g_free (attr_value); |
|
1365 |
|
|
1366 |
sensitive = all_can_set_permissions (file_list); |
|
1367 |
#ifdef HAVE_SELINUX |
|
1368 |
sensitive = sensitive && is_selinux_enabled (); |
|
1369 |
#endif |
|
1370 |
gtk_widget_set_sensitive (GTK_WIDGET (entry), sensitive); |
|
1371 |
} |
|
1372 |
|
|
1373 |
static void |
|
1374 |
edit_field_update (NautilusPropertiesWindow *window, GtkEntry *entry) |
|
1375 |
{ |
|
1376 |
gboolean use_original; |
|
1377 |
|
|
1378 |
if (gtk_widget_is_focus (GTK_WIDGET (entry))) { |
|
1379 |
return; |
|
1380 |
} |
|
1381 |
|
|
1382 |
use_original = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (entry), "show_original")); |
|
1383 |
|
|
1384 |
edit_field_update_internal (entry, |
|
1385 |
(use_original ? |
|
1386 |
window->details->original_files : |
|
1387 |
window->details->target_files)); |
|
1388 |
} |
|
1389 |
|
|
1390 |
static void |
|
1391 |
selinux_combo_update_value (GtkComboBox *combo, const char *new_value) |
|
1392 |
{ |
|
1393 |
GtkTreeModel *model; |
|
1394 |
GtkTreeIter iter; |
|
1395 |
char *cntx_type; |
|
1396 |
gulong handler; |
|
1397 |
|
|
1398 |
g_assert (GTK_IS_COMBO_BOX (combo)); |
|
1399 |
if (! new_value) |
|
1400 |
return; |
|
1401 |
|
|
1402 |
model = gtk_combo_box_get_model (combo); |
|
1403 |
if (! gtk_tree_model_get_iter_first (model, &iter)) |
|
1404 |
return; |
|
1405 |
|
|
1406 |
handler = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo), "handler_changed")); |
|
1407 |
g_signal_handler_block (G_OBJECT (combo), handler); |
|
1408 |
|
|
1409 |
do { |
|
1410 |
gtk_tree_model_get (model, &iter, 0, &cntx_type, -1); |
|
1411 |
|
|
1412 |
if (cntx_type && (g_ascii_strcasecmp (new_value, cntx_type) == 0)) { |
|
1413 |
gtk_combo_box_set_active_iter (combo, &iter); |
|
1414 |
break; |
|
1415 |
} |
|
1416 |
} |
|
1417 |
while (gtk_tree_model_iter_next (model, &iter)); |
|
1418 |
g_signal_handler_unblock (G_OBJECT (combo), handler); |
|
1419 |
} |
|
1420 |
|
|
1421 |
static void |
|
1422 |
popup_field_update_internal (GtkComboBox *combo, |
|
1423 |
GList *file_list) |
|
1424 |
{ |
|
1425 |
const char *attr_name; |
|
1426 |
char *attr_value; |
|
1427 |
char *inconsistent_string; |
|
1428 |
char *cntx_type; |
|
1429 |
const char *attr_u; |
|
1430 |
const char *attr_r; |
|
1431 |
const char *attr_t; |
|
1432 |
const char *attr_s; |
|
1433 |
gboolean sensitive; |
|
1434 |
GtkTreeIter iter; |
|
1435 |
|
|
1436 |
|
|
1437 |
g_assert (GTK_IS_COMBO_BOX (combo)); |
|
1438 |
|
|
1439 |
if (gtk_widget_is_focus (GTK_WIDGET (combo))) { |
|
1440 |
return; |
|
1441 |
} |
|
1442 |
|
|
1443 |
|
|
1444 |
sensitive = all_can_set_permissions (file_list); |
|
1445 |
#ifdef HAVE_SELINUX |
|
1446 |
sensitive = sensitive && is_selinux_enabled (); |
|
1447 |
#endif |
|
1448 |
gtk_widget_set_sensitive (GTK_WIDGET (combo), sensitive); |
|
1449 |
|
|
1450 |
|
|
1451 |
attr_name = g_object_get_data (G_OBJECT (combo), "file_attribute"); |
|
1452 |
inconsistent_string = g_object_get_data (G_OBJECT (combo), |
|
1453 |
"inconsistent_string"); |
|
1454 |
|
|
1455 |
attr_value = file_list_get_string_attribute (file_list, attr_name, |
|
1456 |
inconsistent_string); |
|
1457 |
|
|
1458 |
selinux_split_cntx (attr_value, &attr_u, &attr_r, &attr_t, &attr_s); |
|
1459 |
|
|
1460 |
/* JFIXME: this isn't generic, *sigh* ... */ |
|
1461 |
if (gtk_combo_box_get_active_iter (combo, &iter)) { |
|
1462 |
GtkTreeModel *model = gtk_combo_box_get_model (combo); |
|
1463 |
|
|
1464 |
/* don't update, if it's identical */ |
|
1465 |
gtk_tree_model_get (model, &iter, 0, &cntx_type, -1); |
|
1466 |
if (cntx_type && strcmp (cntx_type, attr_t) == 0) { |
|
1467 |
g_free (attr_value); |
|
1468 |
return; |
|
1469 |
} |
|
1470 |
} |
|
1471 |
|
|
1472 |
selinux_combo_update_value (combo, attr_t); |
|
1473 |
|
|
1474 |
g_free (attr_value); |
|
1475 |
} |
|
1476 |
|
|
1477 |
static void |
|
1478 |
popup_field_update (NautilusPropertiesWindow *window, GtkComboBox *combo) |
|
1479 |
{ |
|
1480 |
gboolean use_original; |
|
1481 |
|
|
1482 |
if (! window->details->selinux_combo) { |
|
1483 |
return; |
|
1484 |
} |
|
1485 |
|
|
1486 |
use_original = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (combo), "show_original")); |
|
1487 |
|
|
1488 |
popup_field_update_internal (combo, |
|
1489 |
(use_original ? |
|
1490 |
window->details->original_files : |
|
1491 |
window->details->target_files)); |
|
1492 |
} |
|
1493 |
|
1201 |
1494 |
static GtkLabel * |
1202 |
1495 |
attach_label (GtkTable *table, |
1203 |
1496 |
int row, |
… |
1252 |
1545 |
return attach_label (table, row, column, initial_text, FALSE, FALSE, FALSE, TRUE, FALSE); |
1253 |
1546 |
} |
1254 |
1547 |
|
|
1548 |
#ifdef HAVE_SELINUX |
|
1549 |
static GtkEntry * |
|
1550 |
attach_edit (GtkTable *table, |
|
1551 |
int row, |
|
1552 |
int column, |
|
1553 |
const char *initial_text, |
|
1554 |
gboolean right_aligned, |
|
1555 |
gboolean bold, |
|
1556 |
gboolean ellipsize_text, |
|
1557 |
gboolean selectable, |
|
1558 |
gboolean mnemonic) |
|
1559 |
{ |
|
1560 |
GtkWidget *entry_field; |
|
1561 |
|
|
1562 |
entry_field = nautilus_entry_new (); |
|
1563 |
gtk_entry_set_text (GTK_ENTRY (entry_field), initial_text); |
|
1564 |
|
|
1565 |
gtk_entry_set_alignment (GTK_ENTRY (entry_field), right_aligned ? 1 : 0); |
|
1566 |
gtk_widget_show (entry_field); |
|
1567 |
gtk_table_attach (table, entry_field, |
|
1568 |
column, column + 1, |
|
1569 |
row, row + 1, |
|
1570 |
ellipsize_text |
|
1571 |
? GTK_FILL | GTK_EXPAND |
|
1572 |
: GTK_FILL, |
|
1573 |
0, |
|
1574 |
0, 0); |
|
1575 |
|
|
1576 |
return GTK_ENTRY (entry_field); |
|
1577 |
} |
|
1578 |
|
|
1579 |
static GtkEntry * |
|
1580 |
attach_edit_label (GtkTable *table, |
|
1581 |
int row, |
|
1582 |
int column, |
|
1583 |
const char *initial_text) |
|
1584 |
{ |
|
1585 |
return attach_edit (table, row, column, initial_text, FALSE, FALSE, FALSE, TRUE, FALSE); |
|
1586 |
} |
|
1587 |
#endif |
|
1588 |
|
1255 |
1589 |
static GtkLabel * |
1256 |
1590 |
attach_ellipsizing_value_label (GtkTable *table, |
1257 |
1591 |
int row, |
… |
1310 |
1644 |
FALSE); |
1311 |
1645 |
} |
1312 |
1646 |
|
|
1647 |
static void |
|
1648 |
start_long_operation (NautilusPropertiesWindow *window) |
|
1649 |
{ |
|
1650 |
if (window->details->long_operation_underway == 0) { |
|
1651 |
/* start long operation */ |
|
1652 |
GdkCursor * cursor; |
|
1653 |
|
|
1654 |
cursor = gdk_cursor_new (GDK_WATCH); |
|
1655 |
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window)), cursor); |
|
1656 |
g_object_unref (cursor); |
|
1657 |
} |
|
1658 |
window->details->long_operation_underway ++; |
|
1659 |
} |
|
1660 |
|
|
1661 |
static void |
|
1662 |
end_long_operation (NautilusPropertiesWindow *window) |
|
1663 |
{ |
|
1664 |
if (gtk_widget_get_window (GTK_WIDGET (window)) != NULL && |
|
1665 |
window->details->long_operation_underway == 1) { |
|
1666 |
/* finished !! */ |
|
1667 |
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window)), NULL); |
|
1668 |
} |
|
1669 |
window->details->long_operation_underway--; |
|
1670 |
} |
|
1671 |
|
|
1672 |
#ifdef HAVE_SELINUX |
|
1673 |
static void |
|
1674 |
selinux_change_callback (NautilusFile *file, |
|
1675 |
GFile *result_location, |
|
1676 |
GError *error, |
|
1677 |
gpointer callback_data) |
|
1678 |
{ |
|
1679 |
NautilusPropertiesWindow *window; |
|
1680 |
g_assert (callback_data != NULL); |
|
1681 |
|
|
1682 |
window = NAUTILUS_PROPERTIES_WINDOW (callback_data); |
|
1683 |
end_long_operation (window); |
|
1684 |
|
|
1685 |
/* Report the error if it's an error. */ |
|
1686 |
nautilus_report_error_setting_selinux (file, error, NULL); |
|
1687 |
|
|
1688 |
g_object_unref (window); |
|
1689 |
} |
|
1690 |
|
|
1691 |
static void |
|
1692 |
selinux_done_editing (NautilusPropertiesWindow *window, char *selinux_context) |
|
1693 |
{ |
|
1694 |
GList *l; |
|
1695 |
|
|
1696 |
/* Accept changes. */ |
|
1697 |
for (l = window->details->target_files; l != NULL; l = l->next) { |
|
1698 |
NautilusFile *file; |
|
1699 |
|
|
1700 |
file = NAUTILUS_FILE (l->data); |
|
1701 |
|
|
1702 |
start_long_operation (window); |
|
1703 |
g_object_ref (window); |
|
1704 |
nautilus_file_set_selinux_context (file, selinux_context, |
|
1705 |
selinux_change_callback, |
|
1706 |
window); |
|
1707 |
} |
|
1708 |
} |
|
1709 |
|
|
1710 |
static gboolean |
|
1711 |
selinux_focus_out (NautilusEntry *entry, GdkEventFocus *event, gpointer cb_data) |
|
1712 |
{ |
|
1713 |
g_assert (NAUTILUS_IS_ENTRY (entry)); |
|
1714 |
g_assert (NAUTILUS_IS_PROPERTIES_WINDOW (cb_data)); |
|
1715 |
|
|
1716 |
if (gtk_widget_get_state (GTK_WIDGET (entry))) { |
|
1717 |
char *tmp; |
|
1718 |
|
|
1719 |
tmp = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1); |
|
1720 |
selinux_done_editing (NAUTILUS_PROPERTIES_WINDOW (cb_data), tmp); |
|
1721 |
g_free (tmp); |
|
1722 |
} |
|
1723 |
|
|
1724 |
return FALSE; |
|
1725 |
} |
|
1726 |
|
|
1727 |
static void |
|
1728 |
selinux_entry_activate (NautilusEntry *entry, gpointer cb_data) |
|
1729 |
{ |
|
1730 |
char *tmp; |
|
1731 |
|
|
1732 |
g_assert (NAUTILUS_IS_ENTRY (entry)); |
|
1733 |
g_assert (NAUTILUS_IS_PROPERTIES_WINDOW (cb_data)); |
|
1734 |
|
|
1735 |
tmp = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1); |
|
1736 |
selinux_done_editing (NAUTILUS_PROPERTIES_WINDOW (cb_data), tmp); |
|
1737 |
g_free (tmp); |
|
1738 |
|
|
1739 |
nautilus_entry_select_all_at_idle (entry); |
|
1740 |
} |
|
1741 |
|
|
1742 |
static void |
|
1743 |
selinux_popup_activate (GtkComboBox *comb, gpointer cb_data) |
|
1744 |
{ |
|
1745 |
char *cntx_type; |
|
1746 |
char *orig_type; |
|
1747 |
const char *attr_u; |
|
1748 |
const char *attr_r; |
|
1749 |
const char *attr_t; |
|
1750 |
const char *attr_s; |
|
1751 |
char *tmp; |
|
1752 |
GtkTreeIter iter; |
|
1753 |
GtkTreeModel *model; |
|
1754 |
|
|
1755 |
g_assert (GTK_IS_COMBO_BOX (comb)); |
|
1756 |
g_assert (NAUTILUS_IS_PROPERTIES_WINDOW (cb_data)); |
|
1757 |
|
|
1758 |
if (!gtk_combo_box_get_active_iter (comb, &iter)) { |
|
1759 |
return; |
|
1760 |
} else { |
|
1761 |
model = gtk_combo_box_get_model (comb); |
|
1762 |
gtk_tree_model_get (model, &iter, 0, &cntx_type, -1); |
|
1763 |
} |
|
1764 |
|
|
1765 |
if (!(orig_type = g_object_get_data (G_OBJECT (comb), "original_cntx"))) { |
|
1766 |
return; |
|
1767 |
} |
|
1768 |
orig_type = g_strdup (orig_type); |
|
1769 |
|
|
1770 |
selinux_split_cntx (orig_type, &attr_u, &attr_r, &attr_t, &attr_s); |
|
1771 |
tmp = g_strjoin (":", attr_u, attr_r, cntx_type, attr_s, NULL); |
|
1772 |
g_free (orig_type); |
|
1773 |
|
|
1774 |
selinux_done_editing (NAUTILUS_PROPERTIES_WINDOW (cb_data), tmp); |
|
1775 |
g_free (tmp); |
|
1776 |
} |
|
1777 |
|
|
1778 |
static char * |
|
1779 |
cust_type_next_line (GIOChannel *ioc_ctypes) |
|
1780 |
{ |
|
1781 |
char *data; |
|
1782 |
gsize term; |
|
1783 |
GError *errc; |
|
1784 |
|
|
1785 |
data = NULL; |
|
1786 |
term = 0; |
|
1787 |
errc = NULL; |
|
1788 |
|
|
1789 |
if (G_IO_STATUS_NORMAL == g_io_channel_read_line (ioc_ctypes, &data, |
|
1790 |
NULL, &term, &errc)) { |
|
1791 |
data[term] = 0; |
|
1792 |
return data; |
|
1793 |
} |
|
1794 |
|
|
1795 |
return NULL; |
|
1796 |
} |
|
1797 |
#endif |
|
1798 |
|
|
1799 |
static GSList * |
|
1800 |
selinux__type_list (void) |
|
1801 |
{ |
|
1802 |
static GSList *cust_types; |
|
1803 |
GSList *scan; |
|
1804 |
#ifdef HAVE_SELINUX |
|
1805 |
static time_t file_mtime; |
|
1806 |
const char *fname_ctypes; |
|
1807 |
struct stat buf; |
|
1808 |
GIOChannel *ioc_ctypes; |
|
1809 |
GError *errc; |
|
1810 |
int fd; |
|
1811 |
#endif |
|
1812 |
|
|
1813 |
#ifndef HAVE_SELINUX |
|
1814 |
if (cust_types) { |
|
1815 |
return cust_types; |
|
1816 |
} |
|
1817 |
#else |
|
1818 |
fname_ctypes = selinux_customizable_types_path (); |
|
1819 |
if (cust_types && file_mtime && !stat (fname_ctypes, &buf) && |
|
1820 |
(file_mtime == buf.st_mtime)) { |
|
1821 |
return cust_types; |
|
1822 |
} |
|
1823 |
#endif |
|
1824 |
|
|
1825 |
if (cust_types) { |
|
1826 |
for (scan = cust_types; scan; scan = scan->next) { |
|
1827 |
g_free (scan->data); |
|
1828 |
} |
|
1829 |
g_slist_free (cust_types); |
|
1830 |
cust_types = NULL; |
|
1831 |
} |
|
1832 |
|
|
1833 |
cust_types = g_slist_prepend (cust_types, g_strdup ("tmp_t")); |
|
1834 |
cust_types = g_slist_prepend (cust_types, g_strdup ("user_home_t")); |
|
1835 |
/* cust_types = g_slist_prepend (cust_types, g_strdup ("user_tmp_t")); */ |
|
1836 |
|
|
1837 |
#ifdef HAVE_SELINUX |
|
1838 |
/* read types, one per line... */ |
|
1839 |
fname_ctypes = selinux_customizable_types_path (); |
|
1840 |
errc = NULL; |
|
1841 |
if ((ioc_ctypes = g_io_channel_new_file (fname_ctypes, "r", &errc))) { |
|
1842 |
char *data = NULL; |
|
1843 |
|
|
1844 |
while ((data = cust_type_next_line (ioc_ctypes))) { |
|
1845 |
cust_types = g_slist_prepend (cust_types, data); |
|
1846 |
} |
|
1847 |
|
|
1848 |
fd = g_io_channel_unix_get_fd (ioc_ctypes); |
|
1849 |
if (!fstat (fd, &buf)) { |
|
1850 |
file_mtime = buf.st_mtime; |
|
1851 |
} |
|
1852 |
|
|
1853 |
g_io_channel_unref (ioc_ctypes); |
|
1854 |
} |
|
1855 |
#endif |
|
1856 |
|
|
1857 |
return cust_types; |
|
1858 |
} |
|
1859 |
|
|
1860 |
static void |
|
1861 |
attach_selinux_data_edit_field (GtkEntry *entry, |
|
1862 |
char *attr_val, char *def_attr_val) |
|
1863 |
{ |
|
1864 |
GtkEntryCompletion *comp; |
|
1865 |
GtkCellRenderer *cell; |
|
1866 |
const char *attr_u; |
|
1867 |
const char *attr_r; |
|
1868 |
const char *attr_t; |
|
1869 |
const char *attr_s; |
|
1870 |
const char *dattr_u; |
|
1871 |
const char *dattr_r; |
|
1872 |
const char *dattr_t; |
|
1873 |
const char *dattr_s; |
|
1874 |
GtkListStore *store; |
|
1875 |
GtkTreeIter iter; |
|
1876 |
GSList *scan; |
|
1877 |
int width; |
|
1878 |
int owidth; |
|
1879 |
int twidth; |
|
1880 |
|
|
1881 |
attr_val = g_strdup (attr_val); /* so we can alter it... */ |
|
1882 |
def_attr_val = g_strdup (def_attr_val); /* so we can alter it... */ |
|
1883 |
|
|
1884 |
/* do completion, so you don't have to type everything... */ |
|
1885 |
comp = gtk_entry_completion_new (); |
|
1886 |
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); |
|
1887 |
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), |
|
1888 |
0, GTK_SORT_ASCENDING); |
|
1889 |
|
|
1890 |
gtk_entry_completion_set_model (comp, GTK_TREE_MODEL (store)); |
|
1891 |
cell = gtk_cell_renderer_pixbuf_new (); |
|
1892 |
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comp), cell, FALSE); |
|
1893 |
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (comp), cell, |
|
1894 |
"stock-id", 1, NULL); |
|
1895 |
gtk_entry_completion_set_text_column (comp, 0); |
|
1896 |
gtk_entry_set_completion (entry, comp); |
|
1897 |
|
|
1898 |
/* FIXME: default doesn't do the right thing, should it? */ |
|
1899 |
owidth = gtk_entry_get_width_chars (entry); |
|
1900 |
width = owidth; |
|
1901 |
|
|
1902 |
selinux_split_cntx (attr_val, &attr_u, &attr_r, &attr_t, &attr_s); |
|
1903 |
dattr_u = dattr_r = dattr_t = dattr_s = NULL; |
|
1904 |
if (def_attr_val) { |
|
1905 |
selinux_split_cntx (def_attr_val, &dattr_u, &dattr_r, |
|
1906 |
&dattr_t, &dattr_s); |
|
1907 |
} |
|
1908 |
|
|
1909 |
/* don't do it twice... */ |
|
1910 |
if (attr_t && dattr_t && !strcmp (attr_t, dattr_t)) { |
|
1911 |
dattr_t = NULL; |
|
1912 |
} |
|
1913 |
|
|
1914 |
if (attr_t && gtk_widget_get_state (GTK_WIDGET (entry))) { |
|
1915 |
/* highlight just the type to the end, so we can easily change it |
|
1916 |
* FIXME: we also highlight any Sensitivity/MCS but completion will |
|
1917 |
* let people put it back, and that's the only way we get completion |
|
1918 |
* at all -- This sucks and we need to remove Sensitivity/MCS from |
|
1919 |
* the edit box. Yah, more UI. */ |
|
1920 |
int beg = attr_t - attr_u; |
|
1921 |
gtk_editable_select_region (GTK_EDITABLE (entry), beg, -1); |
|
1922 |
} |
|
1923 |
|
|
1924 |
for (scan = selinux__type_list(); scan; scan = scan->next) { |
|
1925 |
char *tmp; |
|
1926 |
|
|
1927 |
if (attr_t && !strcmp (attr_t, scan->data)) |
|
1928 |
continue; /* don't have two entries */ |
|
1929 |
|
|
1930 |
if (dattr_t && !strcmp (dattr_t, scan->data)) |
|
1931 |
continue; /* don't have two entries */ |
|
1932 |
|
|
1933 |
gtk_list_store_append (store, &iter); |
|
1934 |
tmp = g_strjoin (":", attr_u, attr_r, scan->data, attr_s, NULL); |
|
1935 |
gtk_list_store_set (store, &iter, 0, tmp, -1); |
|
1936 |
|
|
1937 |
twidth = strlen (tmp); |
|
1938 |
width = MAX (twidth, width); |
|
1939 |
|
|
1940 |
g_free (tmp); |
|
1941 |
} |
|
1942 |
|
|
1943 |
if (dattr_t) { |
|
1944 |
char *tmp; |
|
1945 |
|
|
1946 |
gtk_list_store_append (store, &iter); |
|
1947 |
tmp = g_strjoin (":", dattr_u, dattr_r, dattr_t, dattr_s, NULL); |
|
1948 |
gtk_list_store_set (store, &iter, 0, tmp, |
|
1949 |
1, GTK_STOCK_HOME, -1); |
|
1950 |
|
|
1951 |
twidth = strlen (tmp); |
|
1952 |
width = MAX (twidth, width); |
|
1953 |
|
|
1954 |
g_free (tmp); |
|
1955 |
} |
|
1956 |
|
|
1957 |
if (attr_t) { |
|
1958 |
char *tmp; |
|
1959 |
|
|
1960 |
gtk_list_store_append (store, &iter); |
|
1961 |
tmp = g_strjoin (":", attr_u, attr_r, attr_t, attr_s, NULL); |
|
1962 |
gtk_list_store_set (store, &iter, 0, tmp, 1, GTK_STOCK_OK, -1); |
|
1963 |
|
|
1964 |
twidth = strlen (tmp); |
|
1965 |
width = MAX (twidth, width); |
|
1966 |
|
|
1967 |
g_free (tmp); |
|
1968 |
} |
|
1969 |
|
|
1970 |
g_free (attr_val); |
|
1971 |
g_free (def_attr_val); |
|
1972 |
g_object_unref (G_OBJECT (store)); |
|
1973 |
g_object_unref (G_OBJECT (comp)); |
|
1974 |
|
|
1975 |
if (width != owidth) { |
|
1976 |
gtk_entry_set_width_chars (entry, width + 2); |
|
1977 |
} |
|
1978 |
} |
|
1979 |
|
|
1980 |
#ifdef HAVE_SELINUX |
|
1981 |
|
|
1982 |
# define HACK_TYPE(x, y) \ |
|
1983 |
else if (!strcmp (nice_type, x)) nice_type = y |
|
1984 |
|
|
1985 |
/* hack to convert a selinux_context type into a readable string for the |
|
1986 |
user */ |
|
1987 |
static const char * |
|
1988 |
selinux__hack_conv_type (const char *type) |
|
1989 |
{ /* FIXME: hack attack, but nowhere else to put it. Because mathpathcon |
|
1990 |
* here now probably want a bunch of other types? */ |
|
1991 |
const char *nice_type; |
|
1992 |
|
|
1993 |
nice_type = type; |
|
1994 |
|
|
1995 |
if (0) { } |
|
1996 |
|
|
1997 |
HACK_TYPE("cupsd_etc_t", _("CUPS printer configuration")); |
|
1998 |
HACK_TYPE("cupsd_rw_etc_t", _("CUPS printer configuration (rw)")); |
|
1999 |
HACK_TYPE("cupsd_tmp_t", _("CUPS temporary data")); |
|
2000 |
HACK_TYPE("dhcp_etc_t", _("DHCP configuration")); |
|
2001 |
HACK_TYPE("dictd_etc_t", _("Dictd configuration")); |
|
2002 |
HACK_TYPE("dnssec_t", _("DNS secret")); |
|
2003 |
HACK_TYPE("etc_t", _("System configuration")); |
|
2004 |
HACK_TYPE("etc_aliases_t", _("Email aliases configuration")); |
|
2005 |
HACK_TYPE("etc_runtime_t", _("System configuration (rw)")); |
|
2006 |
HACK_TYPE("cvs_data_t", _("Read and write from CVS daemon")); |
|
2007 |
HACK_TYPE("httpd_config_t", _("Apache-httpd configuration")); |
|
2008 |
HACK_TYPE("httpd_php_tmp_t", |
|
2009 |
_("Apache-httpd PHP module temporary data")); |
|
2010 |
HACK_TYPE("httpd_sys_content_t", |
|
2011 |
_("Read from all httpd scripts and the daemon")); |
|
2012 |
HACK_TYPE("httpd_sys_htaccess_t", |
|
2013 |
_("Apache-httpd .htaccess configuration")); |
|
2014 |
HACK_TYPE("httpd_sys_script_exec_t", |
|
2015 |
_("CGI programs with default access")); |
|
2016 |
HACK_TYPE("httpd_sys_script_ra_t", |
|
2017 |
_("CGI programs can read and append")); |
|
2018 |
HACK_TYPE("httpd_sys_script_ro_t", |
|
2019 |
_("CGI programs can read")); |
|
2020 |
HACK_TYPE("httpd_sys_script_rw_t", |
|
2021 |
_("CGI programs can read and write")); |
|
2022 |
HACK_TYPE("httpd_unconfined_script_exec_t", |
|
2023 |
_("CGI programs without any SELinux protection")); |
|
2024 |
HACK_TYPE("httpd_tmp_t", _("Apache-httpd temporary data")); |
|
2025 |
HACK_TYPE("ice_tmp_t", _("ICE temporary data")); |
|
2026 |
HACK_TYPE("locale_t", _("Locale data")); |
|
2027 |
HACK_TYPE("mysql_tmp_t", _("MySQL temporary data")); |
|
2028 |
HACK_TYPE("named_conf_t", _("Nameserver configuration")); |
|
2029 |
HACK_TYPE("net_conf_t", _("Network configuration")); |
|
2030 |
HACK_TYPE("postgresql_tmp_t", _("Postgresql temporary data")); |
|
2031 |
HACK_TYPE("public_content_rw_t", |
|
2032 |
_("Read and write from CIFS/ftp/http/nfs/rsync")); |
|
2033 |
HACK_TYPE("public_content_t", _("Read from CIFS/ftp/http/nfs/rsync")); |
|
2034 |
HACK_TYPE("samba_etc_t", _("Samba configuration")); |
|
2035 |
HACK_TYPE("samba_share_t", _("Shared via CIFS (samba)")); |
|
2036 |
HACK_TYPE("staff_home_t", _("Staff user data")); |
|
2037 |
HACK_TYPE("staff_home_dir_t", _("Staff user home directory")); |
|
2038 |
HACK_TYPE("swapfile_t", _("System swapfile")); |
|
2039 |
HACK_TYPE("sysadm_home_t", _("Sysadmin user data")); |
|
2040 |
HACK_TYPE("sysadm_home_dir_t", _("Sysadmin user home directory")); |
|
2041 |
HACK_TYPE("system_cron_spool_t", _("Cron data")); |
|
2042 |
HACK_TYPE("tmp_t", _("Temporary data")); |
|
2043 |
HACK_TYPE("user_tmp_t", _("User temporary data")); |
|
2044 |
HACK_TYPE("user_home_t", _("User data")); |
|
2045 |
HACK_TYPE("user_home_dir_t", _("User home directory")); |
|
2046 |
HACK_TYPE("var_log_t", _("Logfile")); |
|
2047 |
HACK_TYPE("xen_image_t", _("Xen image")); |
|
2048 |
|
|
2049 |
return nice_type; |
|
2050 |
} |
|
2051 |
#undef HACK_TYPE |
|
2052 |
|
|
2053 |
static void |
|
2054 |
attach_selinux_data_popup_field (GtkComboBox *comb, |
|
2055 |
char *attr_val, |
|
2056 |
char *def_attr_val) |
|
2057 |
{ |
|
2058 |
const char *attr_u; |
|
2059 |
const char *attr_r; |
|
2060 |
const char *attr_t; |
|
2061 |
const char *attr_s; |
|
2062 |
const char *dattr_u; |
|
2063 |
const char *dattr_r; |
|
2064 |
const char *dattr_t; |
|
2065 |
const char *dattr_s; |
|
2066 |
GtkListStore *store; |
|
2067 |
GtkTreeIter iter; |
|
2068 |
GSList *scan; |
|
2069 |
|
|
2070 |
attr_val = g_strdup (attr_val); /* so we can alter it... */ |
|
2071 |
def_attr_val = g_strdup (def_attr_val); |
|
2072 |
|
|
2073 |
/* do completion, so you don't have to type everything... */ |
|
2074 |
store = gtk_list_store_new (3, G_TYPE_STRING, |
|
2075 |
G_TYPE_STRING, G_TYPE_STRING); |
|
2076 |
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), |
|
2077 |
1, GTK_SORT_ASCENDING); |
|
2078 |
|
|
2079 |
gtk_combo_box_set_model (comb, GTK_TREE_MODEL (store)); |
|
2080 |
|
|
2081 |
selinux_split_cntx (attr_val, &attr_u, &attr_r, &attr_t, &attr_s); |
|
2082 |
dattr_u = dattr_r = dattr_t = dattr_s = NULL; |
|
2083 |
if (def_attr_val) { |
|
2084 |
selinux_split_cntx (def_attr_val, &dattr_u, &dattr_r, |
|
2085 |
&dattr_t, &dattr_s); |
|
2086 |
} |
|
2087 |
/* don't do it twice... */ |
|
2088 |
if (attr_t && dattr_t && !strcmp (attr_t, dattr_t)) { |
|
2089 |
dattr_t = NULL; |
|
2090 |
} |
|
2091 |
|
|
2092 |
for (scan = selinux__type_list(); scan; scan = scan->next) { |
|
2093 |
const char *nice_type; |
|
2094 |
|
|
2095 |
if (attr_t && !strcmp (attr_t, scan->data)) |
|
2096 |
continue; /* don't have two entries */ |
|
2097 |
|
|
2098 |
if (dattr_t && !strcmp (dattr_t, scan->data)) |
|
2099 |
continue; /* don't have two entries */ |
|
2100 |
|
|
2101 |
nice_type = selinux__hack_conv_type(scan->data); |
|
2102 |
|
|
2103 |
gtk_list_store_append (store, &iter); |
|
2104 |
gtk_list_store_set (store, &iter, 0, scan->data, |
|
2105 |
1, nice_type, -1); |
|
2106 |
} |
|
2107 |
|
|
2108 |
if (dattr_t) { |
|
2109 |
const char *nice_type; |
|
2110 |
|
|
2111 |
gtk_list_store_append (store, &iter); |
|
2112 |
nice_type = selinux__hack_conv_type(dattr_t); |
|
2113 |
gtk_list_store_set (store, &iter, 0, dattr_t, 1, nice_type, |
|
2114 |
2, GTK_STOCK_HOME, -1); |
|
2115 |
} |
|
2116 |
|
|
2117 |
if (attr_t) { |
|
2118 |
const char *nice_type; |
|
2119 |
|
|
2120 |
gtk_list_store_append (store, &iter); |
|
2121 |
nice_type = selinux__hack_conv_type(attr_t); |
|
2122 |
gtk_list_store_set (store, &iter, 0, attr_t, 1, nice_type, |
|
2123 |
2, GTK_STOCK_OK, -1); |
|
2124 |
gtk_combo_box_set_active_iter (comb, &iter); |
|
2125 |
} |
|
2126 |
|
|
2127 |
g_free (attr_val); |
|
2128 |
g_free (def_attr_val); |
|
2129 |
g_object_unref (G_OBJECT (store)); |
|
2130 |
} |
|
2131 |
|
|
2132 |
static char * |
|
2133 |
selinux__matchpathcon (GList *file_list) |
|
2134 |
{ |
|
2135 |
GList *scan; |
|
2136 |
|
|
2137 |
for (scan = file_list; scan != NULL; scan = scan->next) { |
|
2138 |
NautilusFile *file; |
|
2139 |
|
|
2140 |
file = NAUTILUS_FILE (scan->data); |
|
2141 |
if (!nautilus_file_is_gone (file)) { |
|
2142 |
return nautilus_file_get_selinux_matchpathcon (file); |
|
2143 |
} |
|
2144 |
} |
|
2145 |
|
|
2146 |
return NULL; |
|
2147 |
} |
|
2148 |
|
|
2149 |
static void |
|
2150 |
attach_selinux_edit_field (NautilusPropertiesWindow *window, |
|
2151 |
GtkTable *table, |
|
2152 |
int row, |
|
2153 |
int column, |
|
2154 |
const char *file_attribute_name, |
|
2155 |
const char *inconsistent_string, |
|
2156 |
gboolean show_original, |
|
2157 |
GtkLabel *lab_title) |
|
2158 |
{ |
|
2159 |
GtkEntry *entry; |
|
2160 |
GList *file_list; |
|
2161 |
char *attr_value; |
|
2162 |
char *def_attr_value; |
|
2163 |
|
|
2164 |
if (show_original) { |
|
2165 |
file_list = window->details->original_files; |
|
2166 |
} else { |
|
2167 |
file_list = window->details->target_files; |
|
2168 |
} |
|
2169 |
|
|
2170 |
attr_value = file_list_get_string_attribute (file_list, |
|
2171 |
file_attribute_name, |
|
2172 |
inconsistent_string); |
|
2173 |
if ( strcmp (attr_value, inconsistent_string) && |
|
2174 |
!strcmp (file_attribute_name, "selinux_context")) { |
|
2175 |
def_attr_value = selinux__matchpathcon (file_list); |
|
2176 |
} else { |
|
2177 |
def_attr_value = NULL; |
|
2178 |
} |
|
2179 |
|
|
2180 |
entry = attach_edit_label (table, row, column, attr_value); |
|
2181 |
gtk_label_set_mnemonic_widget (GTK_LABEL (lab_title), |
|
2182 |
GTK_WIDGET (entry)); |
|
2183 |
|
|
2184 |
/* Stash a copy of the file attribute name in this field for the callback's sake. */ |
|
2185 |
g_object_set_data_full (G_OBJECT (entry), "file_attribute", |
|
2186 |
g_strdup (file_attribute_name), g_free); |
|
2187 |
|
|
2188 |
g_object_set_data_full (G_OBJECT (entry), "inconsistent_string", |
|
2189 |
g_strdup (inconsistent_string), g_free); |
|
2190 |
|
|
2191 |
g_object_set_data (G_OBJECT (entry), "show_original", GINT_TO_POINTER (show_original)); |
|
2192 |
g_object_set_data (G_OBJECT (entry), "ellipsize_text", GINT_TO_POINTER (FALSE)); |
|
2193 |
|
|
2194 |
g_signal_connect_object (entry, "focus_out_event", |
|
2195 |
G_CALLBACK (selinux_focus_out), window, 0); |
|
2196 |
g_signal_connect_object (entry, "activate", |
|
2197 |
G_CALLBACK (selinux_entry_activate), window,0); |
|
2198 |
|
|
2199 |
attach_selinux_data_edit_field (entry, attr_value, def_attr_value); |
|
2200 |
|
|
2201 |
g_object_set_data_full (G_OBJECT (entry), "original_cntx", attr_value, |
|
2202 |
g_free); |
|
2203 |
|
|
2204 |
g_object_set_data_full (G_OBJECT (entry), "matchpathcon_cntx", |
|
2205 |
def_attr_value, g_free); |
|
2206 |
|
|
2207 |
window->details->edit_fields = g_list_prepend (window->details->edit_fields, |
|
2208 |
entry); |
|
2209 |
} |
|
2210 |
|
|
2211 |
static void |
|
2212 |
attach_selinux_popup_field (NautilusPropertiesWindow *window, |
|
2213 |
GtkTable *table, |
|
2214 |
int row, |
|
2215 |
int column, |
|
2216 |
const char *file_attribute_name, |
|
2217 |
const char *inconsistent_string, |
|
2218 |
gboolean show_original, |
|
2219 |
GtkLabel *lab_title) |
|
2220 |
{ |
|
2221 |
GtkWidget *comb; |
|
2222 |
GtkCellRenderer *cell; |
|
2223 |
GList *file_list; |
|
2224 |
char *attr_value; |
|
2225 |
char *def_attr_value; |
|
2226 |
gulong handler; |
|
2227 |
|
|
2228 |
if (show_original) { |
|
2229 |
file_list = window->details->original_files; |
|
2230 |
} else { |
|
2231 |
file_list = window->details->target_files; |
|
2232 |
} |
|
2233 |
|
|
2234 |
attr_value = file_list_get_string_attribute (file_list, |
|
2235 |
file_attribute_name, |
|
2236 |
inconsistent_string); |
|
2237 |
if ( strcmp (attr_value, inconsistent_string) && |
|
2238 |
!strcmp (file_attribute_name, "selinux_context")) { |
|
2239 |
def_attr_value = selinux__matchpathcon (file_list); |
|
2240 |
} else { |
|
2241 |
def_attr_value = NULL; |
|
2242 |
} |
|
2243 |
|
|
2244 |
comb = gtk_combo_box_new (); |
|
2245 |
|
|
2246 |
gtk_table_attach (table, comb, column, column + 1, row, row + 1, |
|
2247 |
GTK_FILL, 0, 0, 0); |
|
2248 |
|
|
2249 |
|
|
2250 |
gtk_label_set_mnemonic_widget (GTK_LABEL (lab_title), comb); |
|
2251 |
|
|
2252 |
/* Stash a copy of the file attribute name in this field for the callback's sake. */ |
|
2253 |
g_object_set_data_full (G_OBJECT (comb), "file_attribute", |
|
2254 |
g_strdup (file_attribute_name), g_free); |
|
2255 |
|
|
2256 |
g_object_set_data (G_OBJECT (comb), "show_original", GINT_TO_POINTER (show_original)); |
|
2257 |
|
|
2258 |
g_object_set_data_full (G_OBJECT (comb), "original_cntx", attr_value, |
|
2259 |
g_free); |
|
2260 |
|
|
2261 |
g_object_set_data_full (G_OBJECT (comb), "matchpathcon_cntx", |
|
2262 |
def_attr_value, g_free); |
|
2263 |
|
|
2264 |
cell = gtk_cell_renderer_pixbuf_new (); |
|
2265 |
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comb), cell, FALSE); |
|
2266 |
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (comb), cell, |
|
2267 |
"stock-id", 2, NULL); |
|
2268 |
cell = gtk_cell_renderer_text_new (); |
|
2269 |
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comb), cell, FALSE); |
|
2270 |
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (comb), cell, |
|
2271 |
"text", 1, NULL); |
|
2272 |
gtk_widget_show (comb); |
|
2273 |
|
|
2274 |
attach_selinux_data_popup_field (GTK_COMBO_BOX (comb), |
|
2275 |
attr_value, def_attr_value); |
|
2276 |
|
|
2277 |
handler = g_signal_connect_object (comb, "changed", |
|
2278 |
G_CALLBACK (selinux_popup_activate), window, 0); |
|
2279 |
g_object_set_data (G_OBJECT (comb), "handler_changed", GUINT_TO_POINTER (handler)); |
|
2280 |
|
|
2281 |
g_assert (! window->details->selinux_combo); |
|
2282 |
|
|
2283 |
window->details->selinux_combo = |
|
2284 |
g_list_prepend (window->details->selinux_combo, comb); |
|
2285 |
} |
|
2286 |
#endif |
|
2287 |
|
1313 |
2288 |
static GtkWidget* |
1314 |
2289 |
attach_ellipsizing_value_field (NautilusPropertiesWindow *window, |
1315 |
2290 |
GtkTable *table, |
… |
2303 |
3278 |
return last_row; |
2304 |
3279 |
} |
2305 |
3280 |
|
|
3281 |
#ifdef HAVE_SELINUX |
|
3282 |
static guint |
|
3283 |
append_title_selinux_edit_pair (NautilusPropertiesWindow *window, |
|
3284 |
GtkTable *table, |
|
3285 |
const char *title, |
|
3286 |
const char *file_attribute_name, |
|
3287 |
const char *inconsistent_state, |
|
3288 |
gboolean show_original) |
|
3289 |
{ |
|
3290 |
guint last_row; |
|
3291 |
GtkLabel *lab_title; |
|
3292 |
|
|
3293 |
lab_title = NULL; |
|
3294 |
last_row = append_title_field (table, title, &lab_title); |
|
3295 |
|
|
3296 |
if (window->details->advanced_permissions) { |
|
3297 |
attach_selinux_edit_field (window, table, last_row, |
|
3298 |
VALUE_COLUMN, file_attribute_name, |
|
3299 |
inconsistent_state, |
|
3300 |
show_original, lab_title); |
|
3301 |
} else { |
|
3302 |
attach_selinux_popup_field (window, table, last_row, |
|
3303 |
VALUE_COLUMN, file_attribute_name, |
|
3304 |
inconsistent_state, |
|
3305 |
show_original, lab_title); |
|
3306 |
} |
|
3307 |
|
|
3308 |
return last_row; |
|
3309 |
} |
|
3310 |
#endif |
|
3311 |
|
2306 |
3312 |
static guint |
2307 |
3313 |
append_title_and_ellipsizing_value (NautilusPropertiesWindow *window, |
2308 |
3314 |
GtkTable *table, |
… |
3228 |
4234 |
} |
3229 |
4235 |
|
3230 |
4236 |
static void |
3231 |
|
start_long_operation (NautilusPropertiesWindow *window) |
3232 |
|
{ |
3233 |
|
if (window->details->long_operation_underway == 0) { |
3234 |
|
/* start long operation */ |
3235 |
|
GdkCursor * cursor; |
3236 |
|
|
3237 |
|
cursor = gdk_cursor_new (GDK_WATCH); |
3238 |
|
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window)), cursor); |
3239 |
|
g_object_unref (cursor); |
3240 |
|
} |
3241 |
|
window->details->long_operation_underway ++; |
3242 |
|
} |
3243 |
|
|
3244 |
|
static void |
3245 |
|
end_long_operation (NautilusPropertiesWindow *window) |
3246 |
|
{ |
3247 |
|
if (gtk_widget_get_window (GTK_WIDGET (window)) != NULL && |
3248 |
|
window->details->long_operation_underway == 1) { |
3249 |
|
/* finished !! */ |
3250 |
|
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window)), NULL); |
3251 |
|
} |
3252 |
|
window->details->long_operation_underway--; |
3253 |
|
} |
3254 |
|
|
3255 |
|
static void |
3256 |
4237 |
permission_change_callback (NautilusFile *file, |
3257 |
4238 |
GFile *res_loc, |
3258 |
4239 |
GError *error, |
… |
4035 |
5016 |
gtk_table_set_row_spacing (table, nrows - 1, 18); |
4036 |
5017 |
} |
4037 |
5018 |
|
4038 |
|
static gboolean |
4039 |
|
all_can_get_permissions (GList *file_list) |
4040 |
|
{ |
4041 |
|
GList *l; |
4042 |
|
for (l = file_list; l != NULL; l = l->next) { |
4043 |
|
NautilusFile *file; |
4044 |
|
|
4045 |
|
file = NAUTILUS_FILE (l->data); |
4046 |
|
|
4047 |
|
if (!nautilus_file_can_get_permissions (file)) { |
4048 |
|
return FALSE; |
4049 |
|
} |
4050 |
|
} |
4051 |
|
|
4052 |
|
return TRUE; |
4053 |
|
} |
4054 |
|
|
4055 |
|
static gboolean |
4056 |
|
all_can_set_permissions (GList *file_list) |
4057 |
|
{ |
4058 |
|
GList *l; |
4059 |
|
for (l = file_list; l != NULL; l = l->next) { |
4060 |
|
NautilusFile *file; |
4061 |
|
|
4062 |
|
file = NAUTILUS_FILE (l->data); |
4063 |
|
|
4064 |
|
if (!nautilus_file_can_set_permissions (file)) { |
4065 |
|
return FALSE; |
4066 |
|
} |
4067 |
|
} |
4068 |
|
|
4069 |
|
return TRUE; |
4070 |
|
} |
4071 |
5019 |
|
4072 |
5020 |
static GHashTable * |
4073 |
5021 |
get_initial_permissions (GList *file_list) |
… |
4415 |
5363 |
guint32 file_permission, file_permission_mask; |
4416 |
5364 |
guint32 dir_permission, dir_permission_mask; |
4417 |
5365 |
guint32 vfs_mask, vfs_new_perm, p; |
4418 |
|
GtkWidget *button, *combo; |
|
5366 |
char *context; |
|
5367 |
GtkWidget *button; |
|
5368 |
GtkComboBox *combo; |
4419 |
5369 |
gboolean active, is_folder, is_special, use_original; |
4420 |
5370 |
GList *l; |
4421 |
5371 |
GtkTreeModel *model; |
… |
4459 |
5409 |
} |
4460 |
5410 |
/* Simple mode, minus exec checkbox */ |
4461 |
5411 |
for (l = window->details->permission_combos; l != NULL; l = l->next) { |
4462 |
|
combo = l->data; |
|
5412 |
combo = GTK_COMBO_BOX (l->data); |
4463 |
5413 |
|
4464 |
|
if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)) { |
|
5414 |
if (!gtk_combo_box_get_active_iter (combo, &iter)) { |
4465 |
5415 |
continue; |
4466 |
5416 |
} |
4467 |
5417 |
|
… |
4469 |
5419 |
is_folder = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (combo), |
4470 |
5420 |
"is-folder")); |
4471 |
5421 |
|
4472 |
|
model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); |
|
5422 |
model = gtk_combo_box_get_model (combo); |
4473 |
5423 |
gtk_tree_model_get (model, &iter, 1, &new_perm, 2, &use_original, -1); |
4474 |
5424 |
if (use_original) { |
4475 |
5425 |
continue; |
… |
4492 |
5442 |
} |
4493 |
5443 |
} |
4494 |
5444 |
|
|
5445 |
/* get the SELinux context... */ |
|
5446 |
context = NULL; |
|
5447 |
if (window->details->advanced_permissions && |
|
5448 |
window->details->edit_fields) { /* advanced mode */ |
|
5449 |
GtkEditable *efield; |
|
5450 |
|
|
5451 |
efield = window->details->edit_fields->data; |
|
5452 |
context = gtk_editable_get_chars (GTK_EDITABLE (efield), 0, -1); |
|
5453 |
} else if (!window->details->advanced_permissions && |
|
5454 |
window->details->selinux_combo) { /* simple mode */ |
|
5455 |
char *cntx_type; |
|
5456 |
char *orig_type; |
|
5457 |
const char *attr_u; |
|
5458 |
const char *attr_r; |
|
5459 |
const char *attr_t; |
|
5460 |
const char *attr_s; |
|
5461 |
|
|
5462 |
combo = GTK_COMBO_BOX (window->details->selinux_combo->data); |
|
5463 |
|
|
5464 |
if (!gtk_combo_box_get_active_iter (combo, &iter)) { |
|
5465 |
return; |
|
5466 |
} else { |
|
5467 |
GtkTreeModel *model = gtk_combo_box_get_model (combo); |
|
5468 |
gtk_tree_model_get (model, &iter, 0, &cntx_type, -1); |
|
5469 |
} |
|
5470 |
if (!(orig_type = g_object_get_data (G_OBJECT (combo), |
|
5471 |
"original_cntx"))) { |
|
5472 |
return; |
|
5473 |
} |
|
5474 |
|
|
5475 |
orig_type = g_strdup (orig_type); |
|
5476 |
|
|
5477 |
selinux_split_cntx (orig_type, |
|
5478 |
&attr_u, &attr_r, &attr_t, &attr_s); |
|
5479 |
context = g_strjoin (":", |
|
5480 |
attr_u, attr_r, cntx_type, attr_s, NULL); |
|
5481 |
g_free (orig_type); |
|
5482 |
} |
|
5483 |
|
4495 |
5484 |
for (l = window->details->target_files; l != NULL; l = l->next) { |
4496 |
5485 |
NautilusFile *file; |
4497 |
5486 |
char *uri; |
4498 |
5487 |
|
4499 |
5488 |
file = NAUTILUS_FILE (l->data); |
4500 |
5489 |
|
|
5490 |
/* assume permissions setting allows context setting... |
|
5491 |
* we can't really do much else due to race conditions anyway */ |
4501 |
5492 |
if (nautilus_file_is_directory (file) && |
4502 |
5493 |
nautilus_file_can_set_permissions (file)) { |
4503 |
5494 |
uri = nautilus_file_get_uri (file); |
… |
4508 |
5499 |
file_permission_mask, |
4509 |
5500 |
dir_permission, |
4510 |
5501 |
dir_permission_mask, |
|
5502 |
context, |
4511 |
5503 |
set_recursive_permissions_done, |
4512 |
5504 |
window); |
4513 |
5505 |
g_free (uri); |
4514 |
5506 |
} |
4515 |
5507 |
} |
|
5508 |
g_free (context); |
4516 |
5509 |
} |
4517 |
5510 |
|
4518 |
5511 |
static void |
… |
4563 |
5556 |
gtk_table_set_row_spacing (page_table, nrows - 1, 18); |
4564 |
5557 |
|
4565 |
5558 |
#ifdef HAVE_SELINUX |
4566 |
|
append_title_value_pair |
4567 |
|
(window, page_table, _("SELinux context:"), |
4568 |
|
"selinux_context", INCONSISTENT_STATE_STRING, |
4569 |
|
FALSE); |
|
5559 |
if (!is_multi_file_window (window) || multi_have_same_selinux_context (window)) |
|
5560 |
append_title_selinux_edit_pair (window, page_table, |
|
5561 |
_("_SELinux Context:"), |
|
5562 |
"selinux_context", INCONSISTENT_STATE_STRING, |
|
5563 |
FALSE); |
|
5564 |
else /* Static text in this case. */ |
|
5565 |
append_title_value_pair (window, page_table, |
|
5566 |
_("_SELinux Context:"), |
|
5567 |
"selinux_context", INCONSISTENT_STATE_STRING, |
|
5568 |
FALSE); |
4570 |
5569 |
#endif |
4571 |
5570 |
append_title_value_pair |
4572 |
5571 |
(window, page_table, _("Last changed:"), |