4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2002, the ROX-Filer team.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* mount.c - code for handling mount points */
33 #elif HAVE_SYS_UCRED_H
34 /* NetBSD, OSF1, etc */
36 # include <sys/types.h>
37 # include <sys/param.h>
38 # include <sys/ucred.h>
39 # include <sys/mount.h>
41 #elif HAVE_SYS_MNTENT_H
43 # include <sys/mntent.h>
44 # include <sys/mnttab.h>
55 /* Map mount points to mntent structures */
56 GHashTable
*fstab_mounts
= NULL
;
59 /* Keys are mount points that the user mounted. Values are ignored. */
60 static GHashTable
*user_mounts
= NULL
;
62 #ifdef HAVE_SYS_MNTENT_H
63 #define THE_FSTAB VFSTAB
65 #define THE_FSTAB "/etc/fstab"
68 /* Static prototypes */
69 #ifdef DO_MOUNT_POINTS
70 static void read_table(void);
71 static void clear_table(void);
72 static time_t read_time(char *path
);
73 static gboolean
free_mp(gpointer key
, gpointer value
, gpointer data
);
77 /****************************************************************
78 * EXTERNAL INTERFACE *
79 ****************************************************************/
83 fstab_mounts
= g_hash_table_new(g_str_hash
, g_str_equal
);
84 user_mounts
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
87 #ifdef DO_MOUNT_POINTS
88 fstab_time
= read_time(THE_FSTAB
);
93 /* If force is true then ignore the timestamps */
94 void mount_update(gboolean force
)
96 #ifdef DO_MOUNT_POINTS
99 time
= read_time(THE_FSTAB
);
100 if (force
|| time
!= fstab_time
)
105 #endif /* DO_MOUNT_POINTS */
108 /* The user has just finished mounting/unmounting this path.
109 * Update the list of user-mounted filesystems.
111 void mount_user_mount(const char *path
)
113 if (mount_is_mounted(path
, NULL
, NULL
))
114 g_hash_table_insert(user_mounts
, pathdup(path
), "yes");
116 g_hash_table_remove(user_mounts
, path
);
119 /* TRUE iff this directory is a mount point. Uses python's method to
121 * The function checks whether path's parent, path/.., is on a different device
122 * than path, or whether path/.. and path point to the same i-node on the same
123 * device -- this should detect mount points for all Unix and POSIX variants.
125 * 'info' and 'parent' are both optional, saving one stat() each.
127 gboolean
mount_is_mounted(const guchar
*path
, struct stat
*info
,
130 struct stat info_path
, info_parent
;
135 if (stat(path
, &info_path
))
136 return FALSE
; /* Doesn't exist => not mount point :-) */
142 parent
= &info_parent
;
143 tmp
= g_strconcat(path
, "/..", NULL
);
144 if (stat(tmp
, &info_parent
))
152 if (info
->st_dev
!= parent
->st_dev
)
155 if (info
->st_ino
== parent
->st_ino
)
156 return TRUE
; /* Same device and inode */
161 /* TRUE if this mount point was mounted by the user, and still is */
162 gboolean
mount_is_user_mounted(const gchar
*path
)
167 real
= pathdup(path
);
169 retval
= g_hash_table_lookup(user_mounts
, path
) != NULL
;
173 /* Check the status is up-to-date */
174 mount_user_mount(real
);
175 retval
= g_hash_table_lookup(user_mounts
, path
) != NULL
;
183 /****************************************************************
184 * INTERNAL FUNCTIONS *
185 ****************************************************************/
188 #ifdef DO_MOUNT_POINTS
190 static gboolean
free_mp(gpointer key
, gpointer value
, gpointer data
)
192 MountPoint
*mp
= (MountPoint
*) value
;
201 /* Remove all entries from mounts table, freeing them as we go */
202 static void clear_table(void)
204 g_hash_table_foreach_remove(fstab_mounts
, free_mp
, NULL
);
207 /* Return the mtime of a file */
208 static time_t read_time(char *path
)
212 g_return_val_if_fail(stat(path
, &info
) == 0, 0);
214 return info
.st_mtime
;
217 # ifdef HAVE_MNTENT_H
218 static void read_table(void)
229 tab
= setmntent(THE_FSTAB
, "r");
230 g_return_if_fail(tab
!= NULL
);
237 fcntl(fileno(tab
), F_SETLKW
, &lb
);
240 while ((ent
= getmntent(tab
)))
242 if (strcmp(ent
->mnt_dir
, "swap") == 0)
245 mp
= g_malloc(sizeof(MountPoint
));
246 mp
->name
= g_strdup(ent
->mnt_fsname
);
247 mp
->dir
= g_strdup(ent
->mnt_dir
);
249 g_hash_table_insert(fstab_mounts
, mp
->dir
, mp
);
255 # elif HAVE_SYS_MNTENT_H
256 static void read_table(void)
267 tab
= fopen(THE_FSTAB
, "r");
268 g_return_if_fail(tab
!= NULL
);
275 fcntl(fileno(tab
), F_SETLKW
, &lb
);
278 while (getmntent(tab
, &ent
)==0)
280 if (strcmp(ent
.mnt_special
, "swap") == 0)
283 mp
= g_malloc(sizeof(MountPoint
));
284 mp
->dir
= g_strdup(ent
.mnt_mountp
);
285 mp
->name
= g_strdup(ent
.mnt_special
);
287 g_hash_table_insert(fstab_mounts
, mp
->dir
, mp
);
293 # elif HAVE_SYS_UCRED_H /* We don't have getmntent(), etc */
295 static void read_table(void)
304 g_return_if_fail(tab
!= 0);
306 while ((ent
= getfsent()))
308 if (strcmp(ent
->fs_vfstype
, "swap") == 0)
310 if (strcmp(ent
->fs_vfstype
, "kernfs") == 0)
313 mp
= g_malloc(sizeof(MountPoint
));
314 mp
->name
= g_strdup(ent
->fs_spec
); /* block special device name */
315 mp
->dir
= g_strdup(ent
->fs_file
); /* file system path prefix */
317 g_hash_table_insert(fstab_mounts
, mp
->dir
, mp
);
323 # endif /* HAVE_MNTENT_H */
325 #endif /* DO_MOUNT_POINTS */