1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2
3 /*
4 * gtk_prop.c
5 *
6 * Copyright (C) 1999 Rasca, Berlin
7 * EMail: thron@gmx.de
8 *
9 * Olivier Fourdan (fourdan@xfce.org)
10 * Heavily modified as part of the Xfce project (http://www.xfce.org)
11 *
12 * 2001/11/13
13 * Takuro Ashie (ashie@homa.ne.jp)
14 * Modified as part of GImageView project
15 * (http://gtkmmviewer.sourceforge.net)
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 *
31 * $Id: gtk_prop.c,v 1.12 2004/09/21 08:44:32 makeinu Exp $
32 */
33
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 #include <string.h>
42 #include <time.h>
43 #include <grp.h>
44 #include <pwd.h>
45 #include <sys/stat.h>
46 #include <sys/wait.h>
47 #include <gtk/gtk.h>
48 #include <gdk/gdkkeysyms.h>
49 #include "intl.h"
50 #include "gtk_prop.h"
51
52 #ifdef DMALLOC
53 # include "dmalloc.h"
54 #endif
55
56 /* FIXME? */
57 #include "prefs.h"
58 #include "charset.h"
59 /* END FIXME? */
60
61
62 #define box_pack_start(box,w) \
63 gtk_box_pack_start(GTK_BOX(box),w,TRUE,FALSE,0)
64 #define box_pack_end(box,w) \
65 gtk_box_pack_end(GTK_BOX(box),w,TRUE,FALSE,0)
66
67 #define X_PAD 8
68 #define Y_PAD 1
69 #define TBL_XOPT GTK_EXPAND
70
71 typedef struct
72 {
73 GtkWidget *top;
74 GtkWidget *user;
75 GtkWidget *group;
76 fprop *prop;
77 int result;
78 int type;
79 } dlg;
80
81 static dlg dl;
82
83
84 /*
85 */
86 static GtkWidget *
label_new(const char * text,GtkJustification j_type)87 label_new (const char *text, GtkJustification j_type)
88 {
89 GtkWidget *label;
90 label = gtk_label_new (text);
91 gtk_label_set_justify (GTK_LABEL (label), j_type);
92 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
93 /* j_type == GTK_JUSTIFY_RIGHT? 1.0 : 0.0, 0.5); */
94 return (label);
95 }
96
97
98 /*
99 */
100 static void
on_cancel(GtkWidget * btn,gpointer * data)101 on_cancel (GtkWidget * btn, gpointer * data)
102 {
103 if ((int) ((long) data) != DLG_RC_DESTROY) {
104 dl.result = (int) ((long) data);
105 gtk_widget_destroy (dl.top);
106 }
107 gtk_main_quit ();
108 }
109
110
111 /*
112 */
113 static void
on_ok(GtkWidget * ok,gpointer * data)114 on_ok (GtkWidget * ok, gpointer * data)
115 {
116 const char *val;
117 struct passwd *pw;
118 struct group *gr;
119
120 val = gtk_entry_get_text (GTK_ENTRY (dl.user));
121 if (val) {
122 pw = getpwnam (val);
123 if (pw) {
124 dl.prop->uid = pw->pw_uid;
125 }
126 }
127 val = gtk_entry_get_text (GTK_ENTRY (dl.group));
128 if (val) {
129 gr = getgrnam (val);
130 if (gr) {
131 dl.prop->gid = gr->gr_gid;
132 }
133 }
134 gtk_widget_destroy (dl.top);
135
136 dl.result = (int) ((long) data);
137 gtk_main_quit ();
138 }
139
140
141 /*
142 */
143 static void
cb_perm(GtkWidget * toggle,void * data)144 cb_perm (GtkWidget * toggle, void *data)
145 {
146 int bit = (int) ((long) data);
147 if (GTK_TOGGLE_BUTTON (toggle)->active)
148 dl.prop->mode |= (mode_t) bit;
149 else
150 dl.prop->mode &= (mode_t) ~ bit;
151 }
152
153
154 /*
155 */
156 static gint
on_key_press(GtkWidget * w,GdkEventKey * event,void * data)157 on_key_press (GtkWidget * w, GdkEventKey * event, void *data)
158 {
159 if (event->keyval == GDK_Escape) {
160 on_cancel ((GtkWidget *) data, (gpointer) ((long) DLG_RC_CANCEL));
161 return (TRUE);
162 }
163 return (FALSE);
164 }
165
166
167 /*
168 * create a modal dialog for properties and handle it
169 */
170 gint
dlg_prop(const gchar * path,fprop * prop,gint flags)171 dlg_prop (const gchar *path, fprop * prop, gint flags)
172 {
173 GtkWidget *ok = NULL, *cancel = NULL, *label, *skip, *all, *notebook, *table;
174 GtkWidget *owner[4], *perm[15], *info[12];
175 struct tm *t;
176 struct passwd *pw;
177 struct group *gr;
178 char buf[PATH_MAX + 1];
179 GList *g_user = NULL;
180 GList *g_group = NULL, *g_tmp;
181 int n, len;
182 #ifndef LINE_MAX
183 #define LINE_MAX 1024
184 #endif
185 char line[LINE_MAX + 1];
186
187
188 dl.result = 0;
189 dl.prop = prop;
190 dl.top = gtk_dialog_new ();
191 gtk_window_set_title (GTK_WINDOW (dl.top), _("Properties"));
192 gtk_signal_connect (GTK_OBJECT (dl.top), "destroy",
193 GTK_SIGNAL_FUNC (on_cancel),
194 (gpointer) ((long) DLG_RC_DESTROY));
195 gtk_window_set_modal (GTK_WINDOW (dl.top), TRUE);
196 gtk_window_set_position (GTK_WINDOW (dl.top), GTK_WIN_POS_MOUSE);
197
198 notebook = gtk_notebook_new ();
199 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dl.top)->vbox), notebook,
200 TRUE, TRUE, 0);
201
202 /* ok and cancel buttons */
203 ok = gtk_button_new_with_label (_("Ok"));
204 cancel = gtk_button_new_with_label (_("Cancel"));
205
206 GTK_WIDGET_SET_FLAGS (ok, GTK_CAN_DEFAULT);
207 GTK_WIDGET_SET_FLAGS (cancel, GTK_CAN_DEFAULT);
208
209 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dl.top)->action_area), ok,
210 TRUE, FALSE, 0);
211 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dl.top)->action_area),
212 cancel, TRUE, FALSE, 0);
213
214 gtk_signal_connect (GTK_OBJECT (ok), "clicked",
215 GTK_SIGNAL_FUNC (on_ok),
216 (gpointer) ((long) DLG_RC_OK));
217 gtk_signal_connect (GTK_OBJECT (cancel), "clicked",
218 GTK_SIGNAL_FUNC (on_cancel),
219 (gpointer) ((long) DLG_RC_CANCEL));
220 gtk_widget_grab_default (ok);
221
222 if (flags & GTK_PROP_MULTI) {
223 skip = gtk_button_new_with_label (_("Skip"));
224 all = gtk_button_new_with_label (_("All"));
225 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dl.top)->action_area), skip,
226 TRUE, FALSE, 0);
227 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dl.top)->action_area), all,
228 TRUE, FALSE, 0);
229 gtk_signal_connect (GTK_OBJECT (skip), "clicked",
230 GTK_SIGNAL_FUNC (on_cancel),
231 (gpointer) ((long) DLG_RC_SKIP));
232 gtk_signal_connect (GTK_OBJECT (all), "clicked",
233 GTK_SIGNAL_FUNC (on_ok),
234 (gpointer) ((long) DLG_RC_ALL));
235 GTK_WIDGET_SET_FLAGS (skip, GTK_CAN_DEFAULT);
236 GTK_WIDGET_SET_FLAGS (all, GTK_CAN_DEFAULT);
237 }
238
239
240 /* date and size page */
241 label = gtk_label_new (_("Info"));
242 table = gtk_table_new (6, 2, FALSE);
243 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), table, label);
244
245 n = 0;
246 info[n] = label_new (_("Name :"), GTK_JUSTIFY_RIGHT);
247 gtk_table_attach (GTK_TABLE (table), info[n], 0, 1, n, n + 1, TBL_XOPT, 0, X_PAD, Y_PAD);
248 {
249 gchar *path_internal;
250 path_internal = charset_to_internal (path,
251 conf.charset_filename,
252 conf.charset_auto_detect_fn,
253 conf.charset_filename_mode);
254 info[n + 1] = label_new (path_internal, GTK_JUSTIFY_LEFT);
255 g_free (path_internal);
256 }
257 gtk_table_attach (GTK_TABLE (table), info[n + 1], 1, 2, n, n + 1, TBL_XOPT, 0, 0, 0);
258 n += 2;
259
260 if (!(flags & GTK_PROP_NOT_DETECT_TYPE)) {
261 pid_t pid;
262 int out_fd[2];
263
264 if (pipe (out_fd) == 0) {
265 pid = fork ();
266 if (pid > 0) {
267 char *p;
268
269 close (out_fd[1]);
270 len = read (out_fd[0], line, LINE_MAX);
271 if (n > 0) {
272 line[len] = '\0';
273 len = strlen(line);
274 if (line[len - 1] == '\n')
275 line[len - 1] = '\0';
276 }
277 waitpid (pid, NULL, WUNTRACED);
278 close (out_fd[0]);
279
280 if ((p = strstr (line, ": ")) != NULL) {
281 p += 2;
282 info[n + 1] = label_new (p, GTK_JUSTIFY_LEFT);
283 info[n] = label_new (_("Type :"), GTK_JUSTIFY_RIGHT);
284 gtk_table_attach (GTK_TABLE (table), info[n], 0, 1, n, n + 1,
285 TBL_XOPT, 0, X_PAD, Y_PAD);
286 gtk_table_attach (GTK_TABLE (table), info[n + 1], 1, 2, n, n + 1,
287 TBL_XOPT, 0, 0, 0);
288 n += 2;
289 }
290 } else if (pid == 0) {
291 gchar **argv = g_new0 (gchar *, 1);
292
293 argv[0] = g_strdup ("file");
294 argv[1] = g_strdup (path);
295 argv[2] = NULL;
296
297 close (out_fd[0]);
298 dup2 (out_fd[1], STDOUT_FILENO);
299
300 execvp (argv[0], argv);
301 }
302 }
303 }
304
305 sprintf (buf, _("%ld Bytes"), (unsigned long) prop->size);
306 info[n + 1] = label_new (buf, GTK_JUSTIFY_LEFT);
307 info[n] = label_new (_("Size :"), GTK_JUSTIFY_RIGHT);
308 gtk_table_attach (GTK_TABLE (table), info[n], 0, 1, n, n + 1,
309 TBL_XOPT, 0, X_PAD, Y_PAD);
310 gtk_table_attach (GTK_TABLE (table), info[n + 1], 1, 2, n, n + 1,
311 TBL_XOPT, 0, 0, 0);
312 n += 2;
313
314 t = localtime (&prop->atime);
315 sprintf (buf, "%04d/%02d/%02d %02d:%02d",
316 t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
317 t->tm_hour, t->tm_min);
318 info[n + 1] = gtk_label_new (buf);
319 info[n] = gtk_label_new (_("Access Time :"));
320 gtk_table_attach (GTK_TABLE (table), info[n], 0, 1, n, n + 1,
321 TBL_XOPT, 0, X_PAD, Y_PAD);
322 gtk_table_attach (GTK_TABLE (table), info[n + 1], 1, 2, n, n + 1,
323 TBL_XOPT, 0, 0, 0);
324 n += 2;
325
326 t = localtime (&prop->mtime);
327 sprintf (buf, "%02d/%02d/%02d %02d:%02d",
328 t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
329 t->tm_hour, t->tm_min);
330 info[n + 1] = gtk_label_new (buf);
331 info[n] = gtk_label_new (_("Modification Time :"));
332 gtk_table_attach (GTK_TABLE (table), info[n], 0, 1, n, n + 1,
333 TBL_XOPT, 0, X_PAD, Y_PAD);
334 gtk_table_attach (GTK_TABLE (table), info[n + 1], 1, 2, n, n + 1,
335 TBL_XOPT, 0, 0, 0);
336 n += 2;
337
338 t = localtime (&prop->ctime);
339 sprintf (buf, "%04d/%02d/%02d %02d:%02d",
340 t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
341 t->tm_hour, t->tm_min);
342 info[n + 1] = gtk_label_new (buf);
343 info[n] = gtk_label_new (_("Change Time :"));
344 gtk_table_attach (GTK_TABLE (table), info[n], 0, 1, n, n + 1,
345 TBL_XOPT, 0, X_PAD, Y_PAD);
346 gtk_table_attach (GTK_TABLE (table), info[n + 1], 1, 2, n, n + 1,
347 TBL_XOPT, 0, 0, 0);
348 n += 2;
349
350 /* permissions page */
351 if (!(flags & GTK_PROP_STALE_LINK)) {
352 label = gtk_label_new (_("Permissions"));
353 table = gtk_table_new (3, 5, FALSE);
354 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), table, label);
355
356 perm[0] = gtk_label_new (_("Owner :"));
357 perm[1] = gtk_check_button_new_with_label (_("Read"));
358 if (prop->mode & S_IRUSR)
359 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[1]), 1);
360 gtk_signal_connect (GTK_OBJECT (perm[1]), "clicked",
361 GTK_SIGNAL_FUNC (cb_perm),
362 (gpointer) ((long) S_IRUSR));
363 perm[2] = gtk_check_button_new_with_label (_("Write"));
364 if (prop->mode & S_IWUSR)
365 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[2]), 1);
366 gtk_signal_connect (GTK_OBJECT (perm[2]), "clicked",
367 GTK_SIGNAL_FUNC (cb_perm),
368 (gpointer) ((long) S_IWUSR));
369 perm[3] = gtk_check_button_new_with_label (_("Execute"));
370 if (prop->mode & S_IXUSR)
371 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[3]), 1);
372 gtk_signal_connect (GTK_OBJECT (perm[3]), "clicked",
373 GTK_SIGNAL_FUNC (cb_perm),
374 (gpointer) ((long) S_IXUSR));
375 perm[4] = gtk_check_button_new_with_label (_("Set UID"));
376 if (prop->mode & S_ISUID)
377 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[4]), 1);
378 gtk_signal_connect (GTK_OBJECT (perm[4]), "clicked",
379 GTK_SIGNAL_FUNC (cb_perm),
380 (gpointer) ((long) S_ISUID));
381
382 gtk_table_attach (GTK_TABLE (table), perm[0], 0, 1, 0, 1, 0, 0, X_PAD, 0);
383 gtk_table_attach (GTK_TABLE (table), perm[1], 1, 2, 0, 1, 0, 0, X_PAD, 0);
384 gtk_table_attach (GTK_TABLE (table), perm[2], 2, 3, 0, 1, 0, 0, X_PAD, 0);
385 gtk_table_attach (GTK_TABLE (table), perm[3], 3, 4, 0, 1, 0, 0, X_PAD, 0);
386 gtk_table_attach (GTK_TABLE (table), perm[4], 4, 5, 0, 1, 0, 0, X_PAD, 0);
387
388 perm[5] = gtk_label_new (_("Group :"));
389 perm[6] = gtk_check_button_new_with_label (_("Read"));
390 if (prop->mode & S_IRGRP)
391 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[6]), 1);
392 gtk_signal_connect (GTK_OBJECT (perm[6]), "clicked",
393 GTK_SIGNAL_FUNC (cb_perm),
394 (gpointer) ((long) S_IRGRP));
395 perm[7] = gtk_check_button_new_with_label (_("Write"));
396 if (prop->mode & S_IWGRP)
397 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[7]), 1);
398 gtk_signal_connect (GTK_OBJECT (perm[7]), "clicked",
399 GTK_SIGNAL_FUNC (cb_perm),
400 (gpointer) ((long) S_IWGRP));
401 perm[8] = gtk_check_button_new_with_label (_("Execute"));
402 if (prop->mode & S_IXGRP)
403 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[8]), 1);
404 gtk_signal_connect (GTK_OBJECT (perm[8]), "clicked",
405 GTK_SIGNAL_FUNC (cb_perm),
406 (gpointer) ((long) S_IXGRP));
407 perm[9] = gtk_check_button_new_with_label (_("Set GID"));
408 if (prop->mode & S_ISGID)
409 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[9]), 1);
410 gtk_signal_connect (GTK_OBJECT (perm[9]), "clicked",
411 GTK_SIGNAL_FUNC (cb_perm),
412 (gpointer) ((long) S_ISGID));
413 gtk_table_attach (GTK_TABLE (table), perm[5], 0, 1, 1, 2, 0, 0, X_PAD, 0);
414 gtk_table_attach (GTK_TABLE (table), perm[6], 1, 2, 1, 2, 0, 0, X_PAD, 0);
415 gtk_table_attach (GTK_TABLE (table), perm[7], 2, 3, 1, 2, 0, 0, X_PAD, 0);
416 gtk_table_attach (GTK_TABLE (table), perm[8], 3, 4, 1, 2, 0, 0, X_PAD, 0);
417 gtk_table_attach (GTK_TABLE (table), perm[9], 4, 5, 1, 2, 0, 0, X_PAD, 0);
418
419 perm[10] = gtk_label_new (_("Other :"));
420 perm[11] = gtk_check_button_new_with_label (_("Read"));
421 if (prop->mode & S_IROTH)
422 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[11]), 1);
423 gtk_signal_connect (GTK_OBJECT (perm[11]), "clicked",
424 GTK_SIGNAL_FUNC (cb_perm),
425 (gpointer) ((long) S_IROTH));
426 perm[12] = gtk_check_button_new_with_label (_("Write"));
427 if (prop->mode & S_IWOTH)
428 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[12]), 1);
429 gtk_signal_connect (GTK_OBJECT (perm[12]), "clicked",
430 GTK_SIGNAL_FUNC (cb_perm),
431 (gpointer) ((long) S_IWOTH));
432 perm[13] = gtk_check_button_new_with_label (_("Execute"));
433 if (prop->mode & S_IXOTH)
434 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[13]), 1);
435 gtk_signal_connect (GTK_OBJECT (perm[13]), "clicked",
436 GTK_SIGNAL_FUNC (cb_perm),
437 (gpointer) ((long) S_IXOTH));
438 perm[14] = gtk_check_button_new_with_label (_("Sticky"));
439 if (prop->mode & S_ISVTX)
440 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (perm[14]), 1);
441 gtk_signal_connect (GTK_OBJECT (perm[14]), "clicked",
442 GTK_SIGNAL_FUNC (cb_perm),
443 (gpointer) ((long) S_ISVTX));
444 gtk_table_attach (GTK_TABLE (table), perm[10], 0, 1, 2, 3, 0, 0, X_PAD, 0);
445 gtk_table_attach (GTK_TABLE (table), perm[11], 1, 2, 2, 3, 0, 0, X_PAD, 0);
446 gtk_table_attach (GTK_TABLE (table), perm[12], 2, 3, 2, 3, 0, 0, X_PAD, 0);
447 gtk_table_attach (GTK_TABLE (table), perm[13], 3, 4, 2, 3, 0, 0, X_PAD, 0);
448 gtk_table_attach (GTK_TABLE (table), perm[14], 4, 5, 2, 3, 0, 0, X_PAD, 0);
449 }
450
451 if (flags & GTK_PROP_EDITABLE) {
452 gint i, n_perms;
453 n_perms = sizeof (perm) / sizeof (GtkWidget *);
454 for (i = 0; i < n_perms; i++) {
455 gtk_widget_set_sensitive (perm[i], FALSE);
456 }
457 }
458
459 /* owner/group page */
460 while ((pw = getpwent ()) != NULL) {
461 g_user = g_list_append (g_user, g_strdup (pw->pw_name));
462 }
463 g_user = g_list_sort (g_user, (GCompareFunc) strcmp);
464 endpwent ();
465
466 while ((gr = getgrent ()) != NULL) {
467 g_group = g_list_append (g_group, g_strdup (gr->gr_name));
468 }
469 endgrent ();
470 g_group = g_list_sort (g_group, (GCompareFunc) strcmp);
471
472 label = gtk_label_new (_("Owner"));
473 table = gtk_table_new (2, 2, FALSE);
474 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), table, label);
475
476 pw = getpwuid (prop->uid);
477 sprintf (buf, "%s", pw ? pw->pw_name : _("unknown"));
478 owner[1] = gtk_combo_new ();
479 dl.user = GTK_WIDGET (GTK_COMBO (owner[1])->entry);
480 if (g_user)
481 gtk_combo_set_popdown_strings (GTK_COMBO (owner[1]), g_user);
482 gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (owner[1])->entry), buf);
483 owner[0] = label_new (_("Owner :"), GTK_JUSTIFY_RIGHT);
484 gtk_table_attach (GTK_TABLE (table), owner[0], 0, 1, 0, 1, 0, 0, X_PAD, Y_PAD);
485 gtk_table_attach (GTK_TABLE (table), owner[1], 1, 2, 0, 1, 0, 0, X_PAD, 0);
486
487 gr = getgrgid (prop->gid);
488 sprintf (buf, "%s", gr ? gr->gr_name : _("unknown"));
489 owner[3] = gtk_combo_new ();
490 dl.group = GTK_WIDGET (GTK_COMBO (owner[3])->entry);
491 if (g_group)
492 gtk_combo_set_popdown_strings (GTK_COMBO (owner[3]), g_group);
493 gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (owner[3])->entry), buf);
494 owner[2] = label_new (_("Group :"), GTK_JUSTIFY_RIGHT);
495 gtk_table_attach (GTK_TABLE (table), owner[2], 0, 1, 1, 2, 0, 0, X_PAD, Y_PAD);
496 gtk_table_attach (GTK_TABLE (table), owner[3], 1, 2, 1, 2, 0, 0, X_PAD, 0);
497
498 if (flags & GTK_PROP_EDITABLE) {
499 gint i, n_owners;
500 n_owners = sizeof (owner) / sizeof (GtkWidget *);
501 for (i = 0; i < n_owners; i++) {
502 gtk_widget_set_sensitive (owner[i], FALSE);
503 }
504 }
505
506 gtk_signal_connect (GTK_OBJECT (dl.top), "key_press_event",
507 GTK_SIGNAL_FUNC (on_key_press),
508 (gpointer) cancel);
509 gtk_widget_show_all (dl.top);
510
511 gtk_main ();
512
513 /* free the lists */
514 g_tmp = g_user;
515 while (g_tmp) {
516 g_free (g_tmp->data);
517 g_tmp = g_tmp->next;
518 }
519 g_list_free (g_user);
520 g_tmp = g_group;
521 while (g_tmp) {
522 g_free (g_tmp->data);
523 g_tmp = g_tmp->next;
524 }
525 g_list_free (g_group);
526 return (dl.result);
527 }
528
529
530 gboolean
dlg_prop_from_image_info(GimvImageInfo * info,gint flags)531 dlg_prop_from_image_info (GimvImageInfo *info, gint flags)
532 {
533 fprop prop;
534 gint rc = DLG_RC_CANCEL;
535 const gchar *path;
536 gboolean retval = FALSE;
537
538 g_return_val_if_fail (info, FALSE);
539
540 path = gimv_image_info_get_path (info);
541
542 prop.mode = info->st.st_mode;
543 prop.uid = info->st.st_uid;
544 prop.gid = info->st.st_gid;
545 prop.ctime = info->st.st_ctime;
546 prop.mtime = info->st.st_mtime;
547 prop.atime = info->st.st_atime;
548 prop.size = info->st.st_size;
549
550 rc = dlg_prop (path, &prop, 0);
551
552 switch (rc) {
553 case DLG_RC_OK:
554 case DLG_RC_ALL:
555 if (prop.mode != info->st.st_mode) {
556 chmod (path, prop.mode);
557 retval = TRUE;
558 }
559 if ((prop.uid != info->st.st_uid) || (prop.gid != info->st.st_gid)) {
560 chown (path, prop.uid, prop.gid);
561 retval = TRUE;
562 }
563 default:
564 break;
565 }
566
567 return retval;
568 }
569