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>
54 /* Map mount points to mntent structures */
55 GHashTable
*fstab_mounts
= NULL
;
58 #ifdef HAVE_SYS_MNTENT_H
59 #define THE_FSTAB VFSTAB
61 #define THE_FSTAB "/etc/fstab"
64 /* Static prototypes */
65 #ifdef DO_MOUNT_POINTS
66 static void read_table(void);
67 static void clear_table(void);
68 static time_t read_time(char *path
);
69 static gboolean
free_mp(gpointer key
, gpointer value
, gpointer data
);
73 /****************************************************************
74 * EXTERNAL INTERFACE *
75 ****************************************************************/
79 fstab_mounts
= g_hash_table_new(g_str_hash
, g_str_equal
);
81 #ifdef DO_MOUNT_POINTS
82 fstab_time
= read_time(THE_FSTAB
);
87 /* If force is true then ignore the timestamps */
88 void mount_update(gboolean force
)
90 #ifdef DO_MOUNT_POINTS
93 time
= read_time(THE_FSTAB
);
94 if (force
|| time
!= fstab_time
)
99 #endif /* DO_MOUNT_POINTS */
102 /* TRUE iff this directory is a mount point. Uses python's method to
104 * The function checks whether path's parent, path/.., is on a different device
105 * than path, or whether path/.. and path point to the same i-node on the same
106 * device -- this should detect mount points for all Unix and POSIX variants.
108 * 'info' and 'parent' are both optional, saving one stat() each.
110 gboolean
mount_is_mounted(const guchar
*path
, struct stat
*info
,
113 struct stat info_path
, info_parent
;
118 if (stat(path
, &info_path
))
119 return FALSE
; /* Doesn't exist => not mount point :-) */
125 parent
= &info_parent
;
126 tmp
= g_strconcat(path
, "/..", NULL
);
127 if (stat(tmp
, &info_parent
))
135 if (info
->st_dev
!= parent
->st_dev
)
138 if (info
->st_ino
== parent
->st_ino
)
139 return TRUE
; /* Same device and inode */
144 /****************************************************************
145 * INTERNAL FUNCTIONS *
146 ****************************************************************/
149 #ifdef DO_MOUNT_POINTS
151 static gboolean
free_mp(gpointer key
, gpointer value
, gpointer data
)
153 MountPoint
*mp
= (MountPoint
*) value
;
162 /* Remove all entries from mounts table, freeing them as we go */
163 static void clear_table(void)
165 g_hash_table_foreach_remove(fstab_mounts
, free_mp
, NULL
);
168 /* Return the mtime of a file */
169 static time_t read_time(char *path
)
173 g_return_val_if_fail(stat(path
, &info
) == 0, 0);
175 return info
.st_mtime
;
178 # ifdef HAVE_MNTENT_H
179 static void read_table(void)
190 tab
= setmntent(THE_FSTAB
, "r");
191 g_return_if_fail(tab
!= NULL
);
198 fcntl(fileno(tab
), F_SETLKW
, &lb
);
201 while ((ent
= getmntent(tab
)))
203 if (strcmp(ent
->mnt_dir
, "swap") == 0)
206 mp
= g_malloc(sizeof(MountPoint
));
207 mp
->name
= g_strdup(ent
->mnt_fsname
);
208 mp
->dir
= g_strdup(ent
->mnt_dir
);
210 g_hash_table_insert(fstab_mounts
, mp
->dir
, mp
);
216 # elif HAVE_SYS_MNTENT_H
217 static void read_table(void)
228 tab
= fopen(THE_FSTAB
, "r");
229 g_return_if_fail(tab
!= NULL
);
236 fcntl(fileno(tab
), F_SETLKW
, &lb
);
239 while (getmntent(tab
, &ent
)==0)
241 if (strcmp(ent
.mnt_special
, "swap") == 0)
244 mp
= g_malloc(sizeof(MountPoint
));
245 mp
->dir
= g_strdup(ent
.mnt_mountp
);
246 mp
->name
= g_strdup(ent
.mnt_special
);
248 g_hash_table_insert(fstab_mounts
, mp
->dir
, mp
);
254 # elif HAVE_SYS_UCRED_H /* We don't have getmntent(), etc */
256 static void read_table(void)
265 g_return_if_fail(tab
!= 0);
267 while ((ent
= getfsent()))
269 if (strcmp(ent
->fs_vfstype
, "swap") == 0)
271 if (strcmp(ent
->fs_vfstype
, "kernfs") == 0)
274 mp
= g_malloc(sizeof(MountPoint
));
275 mp
->name
= g_strdup(ent
->fs_spec
); /* block special device name */
276 mp
->dir
= g_strdup(ent
->fs_file
); /* file system path prefix */
278 g_hash_table_insert(fstab_mounts
, mp
->dir
, mp
);
284 # endif /* HAVE_MNTENT_H */
286 #endif /* DO_MOUNT_POINTS */