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 /* 4.4BSD2 derived systems */
73 #if defined(__bsdi__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
79 /* void error (void); FIXME -- needed? */
82 /* So special that it's not worth putting this in autoconf. */
83 #undef MOUNTED_FREAD_FSTYP
84 #define MOUNTED_GETMNTTBL
88 #include <libgnorba/gnorba.h>
93 #include <sys/types.h>
96 #include "../vfs/vfs.h"
105 /* Information for a mountable device */
110 /* This is just a good guess */
121 option_has_user (char *str
)
124 if ((p
= strstr (str
, "user")) != NULL
) {
125 if ((p
- 2) >= str
) {
126 if (strncmp (p
- 2, "nouser", 6) == 0)
136 #ifdef MOUNTED_GETMNTENT1
138 /* Returns whether the mount entry has the owner flag and our euid matches the
142 option_has_owner (struct mntent
*mnt
)
146 if (strstr (mnt
->mnt_opts
, "owner") == NULL
)
149 if (stat (mnt
->mnt_fsname
, &st
) != 0)
152 if (st
.st_uid
!= geteuid ())
158 /* Returns whether devname is mountable: NULL if it is not or g_strdup()ed
159 * string with the mount point.
162 is_block_device_mountable (char *mount_point
)
168 f
= setmntent ("/etc/fstab", "r");
172 while ((mnt
= getmntent (f
)) != NULL
) {
173 if (strcmp (mnt
->mnt_dir
, mount_point
) != 0) {
174 /* This second test is for compatibility with older
175 * desktops that might be using this.
177 if (strcmp (mnt
->mnt_dir
, mount_point
) != 0)
181 if (getuid () == 0) {
182 retval
= g_strdup (mnt
->mnt_dir
);
186 if (option_has_user (mnt
->mnt_opts
) || option_has_owner (mnt
)) {
187 retval
= g_strdup (mnt
->mnt_dir
);
197 is_block_device_mounted (char *filename
)
201 gboolean retval
= FALSE
;
203 f
= setmntent ("/etc/mtab", "r");
207 while ((mnt
= getmntent (f
)) != NULL
) {
208 if (strcmp (mnt
->mnt_dir
, filename
) == 0)
217 get_mountable_devices (void)
223 f
= setmntent ("/etc/fstab", "r");
225 message (1, MSG_ERROR
, _("Could not open the /etc/fstab file"));
229 while ((mnt
= getmntent (f
)) != NULL
) {
230 if (option_has_user (mnt
->mnt_opts
) || option_has_owner (mnt
)) {
233 dit
= g_new0 (devname_info_t
, 1);
234 dit
->devname
= g_strdup (mnt
->mnt_fsname
);
235 dit
->mount_point
= g_strdup (mnt
->mnt_dir
);
236 dit
->type
= TYPE_UNKNOWN
;
238 if (strcmp (mnt
->mnt_type
, "iso9660") == 0)
239 dit
->type
= TYPE_CDROM
;
241 if (strcmp (mnt
->mnt_type
, "nfs") == 0)
242 dit
->type
= TYPE_NFS
;
244 list
= g_list_prepend (list
, dit
);
250 list
= g_list_reverse (list
);
255 mount_point_to_device (char *mount_point
)
260 f
= setmntent ("/etc/fstab", "r");
264 while ((mnt
= getmntent (f
))) {
265 if (strcmp (mnt
->mnt_dir
, mount_point
) == 0) {
268 v
= g_strdup (mnt
->mnt_fsname
);
282 is_block_device_mountable (char *mount_point
)
288 get_mountable_devices (void)
294 is_block_device_mounted (char *mount_point
)
300 mount_point_to_device (char *mount_point
)
308 /* Returns whether our supported automounter is running */
310 automounter_is_running (void)
312 #if defined(HAVE_CORBA)
314 CORBA_Environment ev
;
315 gboolean result
= FALSE
;
317 CORBA_exception_init (&ev
);
319 server
= goad_server_activate_with_id (NULL
,
320 "GOAD:magicdev:19990913",
321 GOAD_ACTIVATE_EXISTING_ONLY
,
324 if (!CORBA_Object_is_nil (server
, &ev
)) {
325 result
= GNOME_MagicDev_is_running (server
, &ev
);
326 if (ev
._major
!= CORBA_NO_EXCEPTION
)
329 CORBA_Object_release (server
, &ev
);
334 #else /* !HAVE_CORBA */
336 #endif /* HAVE_CORBA */
341 /* Cleans up the desktop directory from device files. Includes block devices
345 desktop_cleanup_devices (void)
350 dir
= mc_opendir (desktop_directory
);
352 g_warning ("Could not clean up desktop devices");
356 gnome_metadata_lock ();
357 while ((dent
= mc_readdir (dir
)) != NULL
) {
362 full_name
= g_concat_dir_and_file (desktop_directory
, dent
->d_name
);
363 if (gnome_metadata_get (full_name
, "is-desktop-device", &size
, &buf
) == 0) {
364 mc_unlink (full_name
);
365 gnome_metadata_delete (full_name
);
370 gnome_metadata_unlock ();
375 /* Creates the desktop link for the specified device */
377 create_device_link (char *dev_name
, char *short_dev_name
, char *caption
, char *icon
,
383 char ejectable_c
= ejectable
;
385 icon_full
= g_concat_dir_and_file (ICONDIR
, icon
);
386 full_name
= g_concat_dir_and_file (desktop_directory
, short_dev_name
);
387 if (mc_symlink (dev_name
, full_name
) != 0) {
390 _("Could not symlink %s to %s; "
391 "will not have such a desktop device icon."),
392 dev_name
, full_name
);
396 gnome_metadata_set (full_name
, "icon-filename", strlen (icon_full
) + 1, icon_full
);
397 gnome_metadata_set (full_name
, "icon-caption", strlen (caption
) + 1, caption
);
398 gnome_metadata_set (full_name
, "device-is-ejectable", 1, &ejectable_c
);
399 gnome_metadata_set (full_name
, "is-desktop-device", 1, &type
); /* hack a boolean value */
405 /* Creates the desktop links to the mountable devices */
417 list
= get_mountable_devices ();
418 automounter
= automounter_is_running ();
425 for (l
= list
; l
; l
= l
->next
) {
426 devname_info_t
*dit
= l
->data
;
428 char *short_dev_name
;
433 gboolean release_format
;
437 dev_name
= dit
->devname
;
438 short_dev_name
= x_basename (dev_name
);
440 release_format
= FALSE
;
444 /* Create the format/icon/count. This could use better heuristics. */
445 if (dit
->type
== TYPE_CDROM
|| strncmp (short_dev_name
, "cdrom", 5) == 0) {
446 format
= _("CD-ROM %d");
447 icon
= "i-cdrom.png";
448 count
= cdrom_count
++;
451 /* If our supported automounter is running, then we can
452 * be nice and create only the links for CD-ROMS that
453 * are actually mounted.
455 if (automounter
&& !is_block_device_mounted (dit
->mount_point
))
457 } else if (strncmp (short_dev_name
, "fd", 2) == 0) {
458 format
= _("Floppy %d");
459 icon
= "i-floppy.png";
460 count
= floppy_count
++;
462 } else if (strncmp (short_dev_name
, "hd", 2) == 0
463 || strncmp (short_dev_name
, "sd", 2) == 0) {
464 format
= _("Disk %d");
465 icon
= "i-blockdev.png";
467 } else if (dit
->type
== TYPE_NFS
) {
468 release_format
= TRUE
;
469 format
= g_strdup_printf (_("NFS dir %s"), dit
->mount_point
);
473 format
= _("Device %d");
474 icon
= "i-blockdev.png";
475 count
= generic_count
++;
478 g_snprintf (buffer
, sizeof (buffer
), format
, count
);
479 if (release_format
) {
484 /* Create the actual link */
487 create_device_link (dit
->mount_point
, short_dev_name
,
488 buffer
, icon
, ejectable
);
490 g_free (dit
->devname
);
491 g_free (dit
->mount_point
);
499 gmount_setup_devices (void)