De-fuzzyed some msgs...
[midnight-commander.git] / gnome / gmount.c
blob4e9b38894c9d3d3c81a648db3b16236a38d06c82
1 /* Mount/umount support for the Midnight Commander
3 * Copyright (C) 1998-1999 The Free Software Foundation
5 * Authors: Miguel de Icaza <miguel@nuclecu.unam.mx>
6 * Federico Mena <federico@nuclecu.unam.mx>
7 */
9 #include <config.h>
10 #include <stdio.h>
12 #ifdef STDC_HEADERS
13 #include <stdlib.h>
14 #else
15 void free (void *ptr);
16 #endif
17 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
18 #include <string.h>
19 #else
20 #include <strings.h>
21 #endif
23 #ifdef HAVE_SYS_PARAM_H
24 #include <sys/param.h>
25 #endif
27 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
28 #include <sys/mount.h>
29 #include <sys/fs_types.h>
30 #endif /* MOUNTED_GETFSSTAT */
32 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
33 #include <mntent.h>
34 #if !defined(MOUNTED)
35 #if defined(MNT_MNTTAB) /* HP-UX. */
36 #define MOUNTED MNT_MNTTAB
37 #endif
38 #if defined(MNTTABNAME) /* Dynix. */
39 #define MOUNTED MNTTABNAME
40 #endif
41 #endif
42 #endif
44 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
45 #include <sys/mount.h>
46 #endif
48 #ifdef MOUNTED_GETMNT /* Ultrix. */
49 #include <sys/mount.h>
50 #include <sys/fs_types.h>
51 #endif
53 #ifdef MOUNTED_FREAD /* SVR2. */
54 #include <mnttab.h>
55 #endif
57 #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
58 #include <mnttab.h>
59 #include <sys/fstyp.h>
60 #include <sys/statfs.h>
61 #endif
63 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
64 #include <sys/mnttab.h>
65 #endif
67 #ifdef MOUNTED_VMOUNT /* AIX. */
68 #include <fshelp.h>
69 #include <sys/vfs.h>
70 #endif
72 /* void error (void); FIXME -- needed? */
74 #ifdef DOLPHIN
75 /* So special that it's not worth putting this in autoconf. */
76 #undef MOUNTED_FREAD_FSTYP
77 #define MOUNTED_GETMNTTBL
78 #endif
80 #ifdef HAVE_CORBA
81 #include <libgnorba/gnorba.h>
82 #include "magicdev.h"
83 #endif /* HAVE_CORBA */
85 #include <dirent.h>
86 #include <sys/types.h>
87 #include <unistd.h>
88 #include <gnome.h>
89 #include "../vfs/vfs.h"
90 #include "dialog.h"
91 #include "gdesktop.h"
92 #include "gmount.h"
93 #include "util.h"
94 #include "i18n.h"
98 /* Information for a mountable device */
99 typedef struct {
100 char *devname;
101 char *mount_point;
103 /* This is just a good guess */
104 enum {
105 TYPE_UNKNOWN,
106 TYPE_CDROM,
107 TYPE_NFS
108 } type;
109 } devname_info_t;
113 static gboolean
114 option_has_user (char *str)
116 char *p;
117 if ((p = strstr (str, "user")) != NULL) {
118 if ((p - 2) >= str) {
119 if (strncmp (p - 2, "nouser", 6) == 0)
120 return FALSE;
122 return TRUE;
124 return FALSE;
129 #ifdef MOUNTED_GETMNTENT1
131 /* Returns whether the mount entry has the owner flag and our euid matches the
132 * device file.
134 static gboolean
135 option_has_owner (struct mntent *mnt)
137 struct stat st;
139 if (strstr (mnt->mnt_opts, "owner") == NULL)
140 return FALSE;
142 if (stat (mnt->mnt_fsname, &st) != 0)
143 return FALSE;
145 if (st.st_uid != geteuid ())
146 return FALSE;
148 return TRUE;
151 /* Returns whether devname is mountable: NULL if it is not or g_strdup()ed
152 * string with the mount point.
154 char *
155 is_block_device_mountable (char *mount_point)
157 FILE *f;
158 struct mntent *mnt;
159 char *retval = NULL;
161 f = setmntent ("/etc/fstab", "r");
162 if (f == NULL)
163 return NULL;
165 while ((mnt = getmntent (f)) != NULL) {
166 if (strcmp (mnt->mnt_dir, mount_point) != 0) {
167 /* This second test is for compatibility with older
168 * desktops that might be using this.
170 if (strcmp (mnt->mnt_dir, mount_point) != 0)
171 continue;
174 if (getuid () == 0) {
175 retval = g_strdup (mnt->mnt_dir);
176 break;
179 if (option_has_user (mnt->mnt_opts) || option_has_owner (mnt)) {
180 retval = g_strdup (mnt->mnt_dir);
181 break;
185 endmntent (f);
186 return retval;
189 gboolean
190 is_block_device_mounted (char *filename)
192 FILE *f;
193 struct mntent *mnt;
194 gboolean retval = FALSE;
196 f = setmntent ("/etc/mtab", "r");
197 if (f == NULL)
198 return FALSE;
200 while ((mnt = getmntent (f)) != NULL) {
201 if (strcmp (mnt->mnt_dir, filename) == 0)
202 retval = TRUE;
205 endmntent (f);
206 return retval;
209 static GList *
210 get_mountable_devices (void)
212 FILE *f;
213 struct mntent *mnt;
214 GList *list = NULL;
216 f = setmntent ("/etc/fstab", "r");
217 if (f == NULL) {
218 message (1, MSG_ERROR, _("Could not open the /etc/fstab file"));
219 return NULL;
222 while ((mnt = getmntent (f)) != NULL) {
223 if (option_has_user (mnt->mnt_opts) || option_has_owner (mnt)) {
224 devname_info_t *dit;
226 dit = g_new0 (devname_info_t, 1);
227 dit->devname = g_strdup (mnt->mnt_fsname);
228 dit->mount_point = g_strdup (mnt->mnt_dir);
229 dit->type = TYPE_UNKNOWN;
231 if (strcmp (mnt->mnt_type, "iso9660") == 0)
232 dit->type = TYPE_CDROM;
234 if (strcmp (mnt->mnt_type, "nfs") == 0)
235 dit->type = TYPE_NFS;
237 list = g_list_prepend (list, dit);
241 endmntent (f);
243 list = g_list_reverse (list);
244 return list;
247 char *
248 mount_point_to_device (char *mount_point)
250 FILE *f;
251 struct mntent *mnt;
253 f = setmntent ("/etc/fstab", "r");
254 if (f == NULL)
255 return NULL;
257 while ((mnt = getmntent (f))) {
258 if (strcmp (mnt->mnt_dir, mount_point) == 0) {
259 char *v;
261 v = g_strdup (mnt->mnt_fsname);
262 endmntent (f);
263 return v;
266 endmntent (f);
267 return NULL;
272 #else
274 char *
275 is_block_device_mountable (char *mount_point)
277 return NULL;
280 static GList *
281 get_mountable_devices (void)
283 return NULL;
286 gboolean
287 is_block_device_mounted (char *mount_point)
289 return TRUE;
292 char *
293 mount_point_to_device (char *mount_point)
295 return NULL;
297 #endif
301 /* Returns whether our supported automounter is running */
302 static gboolean
303 automounter_is_running (void)
305 #if defined(HAVE_CORBA)
306 CORBA_Object server;
307 CORBA_Environment ev;
308 gboolean result = FALSE;
310 CORBA_exception_init (&ev);
312 server = goad_server_activate_with_id (NULL,
313 "GOAD:magicdev:19990913",
314 GOAD_ACTIVATE_EXISTING_ONLY,
315 NULL);
317 if (!CORBA_Object_is_nil (server, &ev)) {
318 result = GNOME_MagicDev_is_running (server, &ev);
319 if (ev._major != CORBA_NO_EXCEPTION)
320 result = FALSE;
322 CORBA_Object_release (server, &ev);
325 return result;
327 #else /* !HAVE_CORBA */
328 return FALSE;
329 #endif /* HAVE_CORBA */
334 /* Cleans up the desktop directory from device files. Includes block devices
335 * and printers.
337 void
338 desktop_cleanup_devices (void)
340 DIR *dir;
341 struct dirent *dent;
343 dir = mc_opendir (desktop_directory);
344 if (!dir) {
345 g_warning ("Could not clean up desktop devices");
346 return;
349 gnome_metadata_lock ();
350 while ((dent = mc_readdir (dir)) != NULL) {
351 char *full_name;
352 char *buf;
353 int size;
355 full_name = g_concat_dir_and_file (desktop_directory, dent->d_name);
356 if (gnome_metadata_get (full_name, "is-desktop-device", &size, &buf) == 0) {
357 mc_unlink (full_name);
358 gnome_metadata_delete (full_name);
359 g_free (buf);
361 g_free (full_name);
363 gnome_metadata_unlock ();
365 mc_closedir (dir);
368 /* Creates the desktop link for the specified device */
369 static void
370 create_device_link (char *dev_name, char *short_dev_name, char *caption, char *icon,
371 gboolean ejectable)
373 char *full_name;
374 char *icon_full;
375 char type = 'D';
376 char ejectable_c = ejectable;
377 struct stat st;
379 icon_full = g_concat_dir_and_file (ICONDIR, icon);
380 full_name = g_concat_dir_and_file (desktop_directory, short_dev_name);
381 if (!mc_lstat (full_name, &st))
382 mc_unlink (full_name);
383 if (mc_symlink (dev_name, full_name) != 0) {
384 message (FALSE,
385 _("Warning"),
386 _("Could not symlink %s to %s; "
387 "will not have such a desktop device icon."),
388 dev_name, full_name);
389 g_free (icon_full);
390 g_free (full_name);
391 return;
394 gnome_metadata_set (full_name, "icon-filename", strlen (icon_full) + 1, icon_full);
395 gnome_metadata_set (full_name, "icon-caption", strlen (caption) + 1, caption);
396 gnome_metadata_set (full_name, "device-is-ejectable", 1, &ejectable_c);
397 gnome_metadata_set (full_name, "is-desktop-device", 1, &type); /* hack a boolean value */
399 g_free (full_name);
400 g_free (icon_full);
403 /* Creates the desktop links to the mountable devices */
404 static void
405 setup_devices (void)
407 GList *list, *l;
408 int floppy_count;
409 int hd_count;
410 int cdrom_count;
411 int generic_count;
412 int automounter;
414 list = get_mountable_devices ();
415 automounter = automounter_is_running ();
417 hd_count = 0;
418 cdrom_count = 0;
419 floppy_count = 0;
420 generic_count = 0;
422 for (l = list; l; l = l->next) {
423 devname_info_t *dit = l->data;
424 char *dev_name;
425 char *short_dev_name;
426 char *format;
427 char *icon;
428 int count;
429 char buffer[128];
430 gboolean release_format;
431 gboolean ejectable;
432 gboolean do_create;
434 dev_name = dit->devname;
435 short_dev_name = x_basename (dev_name);
437 release_format = FALSE;
438 ejectable = FALSE;
439 do_create = TRUE;
441 /* Create the format/icon/count. This could use better heuristics. */
442 if (dit->type == TYPE_CDROM || strncmp (short_dev_name, "cdrom", 5) == 0) {
443 format = _("CD-ROM %d");
444 icon = "i-cdrom.png";
445 count = cdrom_count++;
446 ejectable = TRUE;
448 /* If our supported automounter is running, then we can
449 * be nice and create only the links for CD-ROMS that
450 * are actually mounted.
452 if (automounter && !is_block_device_mounted (dit->mount_point))
453 do_create = FALSE;
454 } else if (strncmp (short_dev_name, "fd", 2) == 0) {
455 format = _("Floppy %d");
456 icon = "i-floppy.png";
457 count = floppy_count++;
458 ejectable = TRUE;
459 } else if (strncmp (short_dev_name, "hd", 2) == 0
460 || strncmp (short_dev_name, "sd", 2) == 0) {
461 format = _("Disk %d");
462 icon = "i-blockdev.png";
463 count = hd_count++;
464 } else if (dit->type == TYPE_NFS) {
465 release_format = TRUE;
466 format = g_strdup_printf (_("NFS dir %s"), dit->mount_point);
467 icon = "i-nfs.png";
468 count = 0; /* unused */
469 } else {
470 format = _("Device %d");
471 icon = "i-blockdev.png";
472 count = generic_count++;
475 g_snprintf (buffer, sizeof (buffer), format, count);
476 if (release_format) {
477 g_free (format);
478 format = NULL;
481 /* Create the actual link */
483 if (do_create)
484 create_device_link (dit->mount_point, short_dev_name,
485 buffer, icon, ejectable);
487 g_free (dit->devname);
488 g_free (dit->mount_point);
489 g_free (dit);
492 g_list_free (list);
495 void
496 gmount_setup_devices (void)
498 setup_devices ();