1
1
mc/gnome/gmount.c
Miguel de Icaza cbebd9cd27 1999-03-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* gdesktop.c (do_mount_umount): Use g_readlink here.

	* gpopup2.c (handle_eject): Small tuning.  And use g_readlink :-).

	* gmount.c (mount_point_to_device): New function.  Mapes a mount
	point to its device.  Required since we are now using the mount
	point (as this is not ambiguous) as the key for the devices and
	the eject command needs the device name, not the mount point.

	* gdesktop.c (desktop_icon_info_open): First try to see if
	filename is mountable.  Then do the directory tests and the file
	launching tests.  Fixes mount-by-double click.

	* gmount.c (setup_devices): Use new tigert icon.
1999-03-11 07:53:26 +00:00

424 строки
8.2 KiB
C

/* Mount/umount support for the Midnight Commander
*
* Copyright (C) 1998-1999 The Free Software Foundation
*
* Authors: Miguel de Icaza <miguel@nuclecu.unam.mx>
* Federico Mena <federico@nuclecu.unam.mx>
*/
#include <config.h>
#include <stdio.h>
#ifdef STDC_HEADERS
#include <stdlib.h>
#else
void free (void *ptr);
#endif
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
#include <string.h>
#else
#include <strings.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
#include <sys/mount.h>
#include <sys/fs_types.h>
#endif /* MOUNTED_GETFSSTAT */
#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
#include <mntent.h>
#if !defined(MOUNTED)
#if defined(MNT_MNTTAB) /* HP-UX. */
#define MOUNTED MNT_MNTTAB
#endif
#if defined(MNTTABNAME) /* Dynix. */
#define MOUNTED MNTTABNAME
#endif
#endif
#endif
#ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
#include <sys/mount.h>
#endif
#ifdef MOUNTED_GETMNT /* Ultrix. */
#include <sys/mount.h>
#include <sys/fs_types.h>
#endif
#ifdef MOUNTED_FREAD /* SVR2. */
#include <mnttab.h>
#endif
#ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
#include <mnttab.h>
#include <sys/fstyp.h>
#include <sys/statfs.h>
#endif
#ifdef MOUNTED_GETMNTENT2 /* SVR4. */
#include <sys/mnttab.h>
#endif
#ifdef MOUNTED_VMOUNT /* AIX. */
#include <fshelp.h>
#include <sys/vfs.h>
#endif
/* 4.4BSD2 derived systems */
#if defined(__bsdi__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
# ifndef MOUNT_UFS
# define xBSD
# endif
#endif
/* void error (void); FIXME -- needed? */
#ifdef DOLPHIN
/* So special that it's not worth putting this in autoconf. */
#undef MOUNTED_FREAD_FSTYP
#define MOUNTED_GETMNTTBL
#endif
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>
#include <gnome.h>
#include "../vfs/vfs.h"
#include "dialog.h"
#include "gdesktop.h"
#include "gmount.h"
#include "util.h"
typedef struct {
char *devname;
char *mount_point;
/* This is just a good guess */
enum {
TYPE_UNKNOWN,
TYPE_CDROM,
TYPE_NFS
} type;
} devname_info_t;
static gboolean
option_has_user (char *str)
{
char *p;
if ((p = strstr (str, "user")) != NULL){
if ((p - 2) >= str){
if (strncmp (p - 2, "nouser", 6) == 0)
return FALSE;
}
return TRUE;
}
return FALSE;
}
#ifdef MOUNTED_GETMNTENT1
/*
* Returns wheter devname is mountable:
* NULL if it is not or
* g_strdup()ed string with the mount point
*/
char *
is_block_device_mountable (char *mount_point)
{
FILE *f;
struct mntent *mnt;
char *retval = NULL;
if (getuid () == 0)
return NULL;
f = setmntent ("/etc/fstab", "r");
if (f == NULL)
return NULL;
while ((mnt = getmntent (f))){
if (strcmp (mnt->mnt_dir, mount_point) != 0){
/*
* This second test is for compatibility with older
* desktops that might be using this
*/
if (strcmp (mnt->mnt_dir, mount_point) != 0)
continue;
}
if (option_has_user (mnt->mnt_opts)){
retval = g_strdup (mnt->mnt_dir);
break;
}
}
endmntent (f);
return retval;
}
gboolean
is_block_device_mounted (char *filename)
{
FILE *f;
struct mntent *mnt;
gboolean retval = FALSE;
f = setmntent ("/etc/mtab", "r");
if (f == NULL)
return FALSE;
while ((mnt = getmntent (f))){
if (strcmp (mnt->mnt_dir, filename) == 0)
retval = TRUE;
}
endmntent (f);
return retval;
}
static GList *
get_mountable_devices (void)
{
FILE *f;
struct mntent *mnt;
GList *list = NULL;
f = setmntent ("/etc/fstab", "r");
if (f == NULL)
return NULL;
while ((mnt = getmntent (f))){
if (option_has_user (mnt->mnt_opts)){
devname_info_t *dit;
dit = g_new0 (devname_info_t, 1);
dit->devname = g_strdup (mnt->mnt_fsname);
dit->mount_point = g_strdup (mnt->mnt_dir);
dit->type = TYPE_UNKNOWN;
if (strcmp (mnt->mnt_type, "iso9660") == 0)
dit->type = TYPE_CDROM;
if (strcmp (mnt->mnt_type, "nfs") == 0)
dit->type = TYPE_NFS;
list = g_list_prepend (list, dit);
}
}
endmntent (f);
return list;
}
char *
mount_point_to_device (char *mount_point)
{
FILE *f;
struct mntent *mnt;
f = setmntent ("/etc/fstab", "r");
if (f == NULL)
return NULL;
while ((mnt = getmntent (f))){
if (strcmp (mnt->mnt_dir, mount_point) == 0){
char *v;
v = g_strdup (mnt->mnt_fsname);
endmntent (f);
return v;
}
}
endmntent (f);
return NULL;
}
#else
char *
is_block_device_mountable (char *mount_point)
{
return NULL;
}
static GList *
get_mountable_devices (void)
{
return NULL;
}
gboolean
is_block_device_mounted (char *mount_point)
{
return TRUE;
}
char *
mount_point_to_device (char *mount_point)
{
return NULL;
}
#endif
/*
* Cleans up the desktop directory from device files
*
* Includes block devices and printers.
*/
void
desktop_cleanup_devices (void)
{
DIR *dir;
struct dirent *dent;
dir = mc_opendir (desktop_directory);
if (!dir) {
g_warning ("Could not clean up desktop devices");
return;
}
gnome_metadata_lock ();
while ((dent = mc_readdir (dir)) != NULL) {
char *full_name;
char *buf;
int size;
full_name = g_concat_dir_and_file (desktop_directory, dent->d_name);
if (gnome_metadata_get (full_name, "is-desktop-device", &size, &buf) == 0) {
mc_unlink (full_name);
gnome_metadata_delete (full_name);
g_free (buf);
}
g_free (full_name);
}
gnome_metadata_unlock ();
mc_closedir (dir);
}
/* Creates the desktop link for the specified device */
static void
create_device_link (char *dev_name, char *short_dev_name, char *caption, char *icon, gboolean ejectable)
{
char *full_name;
char *icon_full;
char type = 'D';
char ejectable_c = ejectable;
icon_full = g_concat_dir_and_file (ICONDIR, icon);
full_name = g_concat_dir_and_file (desktop_directory, short_dev_name);
if (mc_symlink (dev_name, full_name) != 0) {
message (FALSE,
_("Warning"),
_("Could not symlink %s to %s; "
"will not have such a desktop device icon."),
dev_name, full_name);
return;
}
gnome_metadata_set (full_name, "icon-filename", strlen (icon_full) + 1, icon_full);
gnome_metadata_set (full_name, "icon-caption", strlen (caption) + 1, caption);
gnome_metadata_set (full_name, "device-is-ejectable", 1, &ejectable_c);
gnome_metadata_set (full_name, "is-desktop-device", 1, &type); /* hack a boolean value */
g_free (full_name);
g_free (icon_full);
}
/* Creates the desktop links to the mountable devices */
static void
setup_devices (void)
{
GList *list, *l;
int floppy_count;
int hd_count;
int cdrom_count;
int generic_count;
int nfs_count;
list = get_mountable_devices ();
hd_count = 0;
cdrom_count = 0;
floppy_count = 0;
generic_count = 0;
for (l = list; l; l = l->next) {
devname_info_t *dit = l->data;
char *dev_name;
char *short_dev_name;
char *format;
char *icon;
int count;
char buffer[128];
gboolean release_format;
gboolean ejectable;
dev_name = dit->devname;
short_dev_name = x_basename (dev_name);
release_format = FALSE;
ejectable = FALSE;
/* Create the format/icon/count. This could use better heuristics. */
if (dit->type == TYPE_CDROM){
format = _("CD-ROM %d");
icon = "i-cdrom.png";
count = cdrom_count++;
ejectable = TRUE;
} else if (strncmp (short_dev_name, "fd", 2) == 0) {
format = _("Floppy %d");
icon = "i-floppy.png";
count = floppy_count++;
ejectable = TRUE;
} else if (strncmp (short_dev_name, "hd", 2) == 0
|| strncmp (short_dev_name, "sd", 2) == 0) {
format = _("Disk %d");
icon = "i-blockdev.png";
count = hd_count++;
} else if (strncmp (short_dev_name, "cdrom", 5) == 0){
format = _("CD-ROM %d");
icon = "i-cdrom.png";
count = cdrom_count++;
ejectable = TRUE;
} else if (dit->type == TYPE_NFS){
release_format = TRUE;
format = g_strdup_printf (_("NFS dir %s"), dit->mount_point);
icon = "i-nfs.png";
count = nfs_count++;
} else {
format = _("Device %d");
icon = "i-blockdev.png";
count = generic_count++;
}
g_snprintf (buffer, sizeof (buffer), format, count);
if (release_format){
g_free (format);
format = NULL;
}
/* Create the actual link */
create_device_link (dit->mount_point, short_dev_name, buffer, icon, ejectable);
g_free (dit->devname);
g_free (dit->mount_point);
g_free (dit);
}
g_list_free (list);
}
void
gmount_setup_devices (void)
{
setup_devices ();
}