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>
15 void free (void *ptr
);
17 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
23 #ifdef HAVE_SYS_PARAM_H
24 #include <sys/param.h>
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. */
35 #if defined(MNT_MNTTAB) /* HP-UX. */
36 #define MOUNTED MNT_MNTTAB
38 #if defined(MNTTABNAME) /* Dynix. */
39 #define MOUNTED MNTTABNAME
44 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
45 #include <sys/mount.h>
48 #ifdef MOUNTED_GETMNT /* Ultrix. */
49 #include <sys/mount.h>
50 #include <sys/fs_types.h>
53 #ifdef MOUNTED_FREAD /* SVR2. */
57 #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
59 #include <sys/fstyp.h>
60 #include <sys/statfs.h>
63 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
64 #include <sys/mnttab.h>
67 #ifdef MOUNTED_VMOUNT /* AIX. */
72 /* void error (void); FIXME -- needed? */
75 /* So special that it's not worth putting this in autoconf. */
76 #undef MOUNTED_FREAD_FSTYP
77 #define MOUNTED_GETMNTTBL
81 #include <libgnorba/gnorba.h>
83 #endif /* HAVE_CORBA */
86 #include <sys/types.h>
89 #include "../vfs/vfs.h"
98 /* Information for a mountable device */
103 /* This is just a good guess */
114 option_has_user (char *str
)
117 if ((p
= strstr (str
, "user")) != NULL
) {
118 if ((p
- 2) >= str
) {
119 if (strncmp (p
- 2, "nouser", 6) == 0)
129 #ifdef MOUNTED_GETMNTENT1
131 /* Returns whether the mount entry has the owner flag and our euid matches the
135 option_has_owner (struct mntent
*mnt
)
139 if (strstr (mnt
->mnt_opts
, "owner") == NULL
)
142 if (stat (mnt
->mnt_fsname
, &st
) != 0)
145 if (st
.st_uid
!= geteuid ())
151 /* Returns whether devname is mountable: NULL if it is not or g_strdup()ed
152 * string with the mount point.
155 is_block_device_mountable (char *mount_point
)
161 f
= setmntent ("/etc/fstab", "r");
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)
174 if (getuid () == 0) {
175 retval
= g_strdup (mnt
->mnt_dir
);
179 if (option_has_user (mnt
->mnt_opts
) || option_has_owner (mnt
)) {
180 retval
= g_strdup (mnt
->mnt_dir
);
190 is_block_device_mounted (char *filename
)
194 gboolean retval
= FALSE
;
196 f
= setmntent ("/etc/mtab", "r");
200 while ((mnt
= getmntent (f
)) != NULL
) {
201 if (strcmp (mnt
->mnt_dir
, filename
) == 0)
210 get_mountable_devices (void)
216 f
= setmntent ("/etc/fstab", "r");
218 message (1, MSG_ERROR
, _("Could not open the /etc/fstab file"));
222 while ((mnt
= getmntent (f
)) != NULL
) {
223 if (option_has_user (mnt
->mnt_opts
) || option_has_owner (mnt
)) {
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
);
243 list
= g_list_reverse (list
);
248 mount_point_to_device (char *mount_point
)
253 f
= setmntent ("/etc/fstab", "r");
257 while ((mnt
= getmntent (f
))) {
258 if (strcmp (mnt
->mnt_dir
, mount_point
) == 0) {
261 v
= g_strdup (mnt
->mnt_fsname
);
275 is_block_device_mountable (char *mount_point
)
281 get_mountable_devices (void)
287 is_block_device_mounted (char *mount_point
)
293 mount_point_to_device (char *mount_point
)
301 /* Returns whether our supported automounter is running */
303 automounter_is_running (void)
305 #if defined(HAVE_CORBA)
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
,
317 if (!CORBA_Object_is_nil (server
, &ev
)) {
318 result
= GNOME_MagicDev_is_running (server
, &ev
);
319 if (ev
._major
!= CORBA_NO_EXCEPTION
)
322 CORBA_Object_release (server
, &ev
);
327 #else /* !HAVE_CORBA */
329 #endif /* HAVE_CORBA */
334 /* Cleans up the desktop directory from device files. Includes block devices
338 desktop_cleanup_devices (void)
343 dir
= mc_opendir (desktop_directory
);
345 g_warning ("Could not clean up desktop devices");
349 gnome_metadata_lock ();
350 while ((dent
= mc_readdir (dir
)) != NULL
) {
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
);
363 gnome_metadata_unlock ();
368 /* Creates the desktop link for the specified device */
370 create_device_link (char *dev_name
, char *short_dev_name
, char *caption
, char *icon
,
376 char ejectable_c
= ejectable
;
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) {
386 _("Could not symlink %s to %s; "
387 "will not have such a desktop device icon."),
388 dev_name
, full_name
);
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 */
403 /* Creates the desktop links to the mountable devices */
414 list
= get_mountable_devices ();
415 automounter
= automounter_is_running ();
422 for (l
= list
; l
; l
= l
->next
) {
423 devname_info_t
*dit
= l
->data
;
425 char *short_dev_name
;
430 gboolean release_format
;
434 dev_name
= dit
->devname
;
435 short_dev_name
= x_basename (dev_name
);
437 release_format
= FALSE
;
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
++;
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
))
454 } else if (strncmp (short_dev_name
, "fd", 2) == 0) {
455 format
= _("Floppy %d");
456 icon
= "i-floppy.png";
457 count
= floppy_count
++;
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";
464 } else if (dit
->type
== TYPE_NFS
) {
465 release_format
= TRUE
;
466 format
= g_strdup_printf (_("NFS dir %s"), dit
->mount_point
);
468 count
= 0; /* unused */
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
) {
481 /* Create the actual link */
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
);
496 gmount_setup_devices (void)