r898: Applied Bernard Jungen's latest patch:
[rox-filer.git] / ROX-Filer / src / mount.c
blob475edb79875a78bdbed1fe91d589f72ea255149f
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2001, 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)
10 * any later version.
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
15 * more details.
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 */
24 #include "config.h"
25 #include <stdio.h>
26 #include <string.h>
27 #ifdef HAVE_FCNTL_H
28 #include <fcntl.h>
29 #endif
30 #ifdef HAVE_MNTENT_H
31 /* Linux, etc */
32 # include <mntent.h>
33 #elif HAVE_SYS_UCRED_H
34 /* NetBSD, OSF1, etc */
35 # include <fstab.h>
36 # include <sys/types.h>
37 # include <sys/param.h>
38 # include <sys/ucred.h>
39 # include <sys/mount.h>
40 # include <stdlib.h>
41 #elif HAVE_SYS_MNTENT_H
42 /* SunOS */
43 # include <sys/mntent.h>
44 # include <sys/mnttab.h>
45 #endif
46 #include <sys/time.h>
48 #include <gtk/gtk.h>
50 #include "global.h"
52 #include "mount.h"
54 /* Map mount points to mntent structures */
55 GHashTable *fstab_mounts = NULL;
56 time_t fstab_time;
58 #ifdef HAVE_SYS_MNTENT_H
59 #define THE_FSTAB VFSTAB
60 #else
61 #define THE_FSTAB "/etc/fstab"
62 #endif
64 /* Static prototypes */
65 #ifdef DO_MOUNT_POINTS
66 static void read_table(void);
67 static void clear_table(GHashTable *table);
68 static time_t read_time(char *path);
69 static gboolean free_mp(gpointer key, gpointer value, gpointer data);
70 #endif
73 /****************************************************************
74 * EXTERNAL INTERFACE *
75 ****************************************************************/
77 void mount_init(void)
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);
83 read_table();
84 #endif
87 /* If force is true then ignore the timestamps */
88 void mount_update(gboolean force)
90 #ifdef DO_MOUNT_POINTS
91 time_t time;
93 time = read_time(THE_FSTAB);
94 if (force || time != fstab_time)
96 fstab_time = time;
97 read_table();
99 #endif /* DO_MOUNT_POINTS */
102 /* TRUE iff this directory is a mount point. Uses python's method to
103 * check:
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 gboolean mount_is_mounted(guchar *path)
110 struct stat info_path, info_parent;
111 guchar *tmp;
113 if (stat(path, &info_path))
114 return FALSE; /*It doesn't exist -- so not a mount point :-) */
116 tmp = g_strconcat(path, "/..", NULL);
117 if (stat(tmp, &info_parent))
119 g_free(tmp);
120 return FALSE;
122 g_free(tmp);
124 if (info_path.st_dev != info_parent.st_dev)
125 return TRUE;
127 if (info_path.st_ino == info_parent.st_ino)
128 return TRUE; /* Same device and inode */
130 return FALSE;
133 /****************************************************************
134 * INTERNAL FUNCTIONS *
135 ****************************************************************/
138 #ifdef DO_MOUNT_POINTS
140 static gboolean free_mp(gpointer key, gpointer value, gpointer data)
142 MountPoint *mp = (MountPoint *) value;
144 g_free(mp->name);
145 g_free(mp->dir);
146 g_free(mp);
148 return TRUE;
151 /* Remove all entries from a hash table, freeing them as we go */
152 static void clear_table(GHashTable *table)
154 g_hash_table_foreach_remove(table, free_mp, NULL);
157 /* Return the mtime of a file */
158 static time_t read_time(char *path)
160 struct stat info;
162 g_return_val_if_fail(stat(path, &info) == 0, 0);
164 return info.st_mtime;
167 # ifdef HAVE_MNTENT_H
168 static void read_table(void)
170 FILE *tab;
171 struct mntent *ent;
172 MountPoint *mp;
174 clear_table(fstab_mounts);
176 tab = setmntent(THE_FSTAB, "r");
177 g_return_if_fail(tab != NULL);
179 while ((ent = getmntent(tab)))
181 if (strcmp(ent->mnt_dir, "swap") == 0)
182 continue;
184 mp = g_malloc(sizeof(MountPoint));
185 mp->name = g_strdup(ent->mnt_fsname);
186 mp->dir = g_strdup(ent->mnt_dir);
188 g_hash_table_insert(fstab_mounts, mp->dir, mp);
191 endmntent(tab);
194 # elif HAVE_SYS_MNTENT_H
195 static void read_table(void)
197 FILE *tab;
198 struct mnttab ent;
199 MountPoint *mp;
200 # ifdef HAVE_FCNTL_H
201 struct flock lb;
202 # endif
204 tab = fopen(THE_FSTAB, "r");
205 g_return_if_fail(tab != NULL);
206 clear_table(fstab_mounts);
208 # ifdef HAVE_FCNTL_H
209 lb.l_type = F_RDLCK;
210 lb.l_whence = 0;
211 lb.l_start = 0;
212 lb.l_len = 0;
213 fcntl(fileno(tab), F_SETLKW, &lb);
214 # endif
216 while (getmntent(tab, &ent)==0)
218 if (strcmp(ent.mnt_special, "swap") == 0)
219 continue;
221 mp = g_malloc(sizeof(MountPoint));
222 mp->dir = g_strdup(ent.mnt_mountp);
223 mp->name = g_strdup(ent.mnt_special);
225 g_hash_table_insert(fstab_mounts, mp->dir, mp);
228 fclose(tab);
231 # elif HAVE_SYS_UCRED_H /* We don't have getmntent(), etc */
233 static void read_table(void)
235 int tab;
236 struct fstab *ent;
237 MountPoint *mp;
239 clear_table(fstab_mounts);
241 tab = setfsent();
242 g_return_if_fail(tab != 0);
244 while ((ent = getfsent()))
246 if (strcmp(ent->fs_vfstype, "swap") == 0)
247 continue;
248 if (strcmp(ent->fs_vfstype, "kernfs") == 0)
249 continue;
251 mp = g_malloc(sizeof(MountPoint));
252 mp->name = g_strdup(ent->fs_spec); /* block special device name */
253 mp->dir = g_strdup(ent->fs_file); /* file system path prefix */
255 g_hash_table_insert(fstab_mounts, mp->dir, mp);
258 endfsent();
261 # endif /* HAVE_MNTENT_H */
263 #endif /* DO_MOUNT_POINTS */