r103: Added config.h.in autoconf header file.
[rox-filer.git] / ROX-Filer / src / mount.c
blob6b488406b25a0e662c74e53f0037455a4c580c9e
1 /* vi: set cindent:
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * By Thomas Leonard, <tal197@ecs.soton.ac.uk>.
6 */
8 /* mount.c - code for handling mount points */
10 #include <config.h>
11 #include <stdio.h>
12 #ifdef HAVE_MNTENT_H
13 /* Linux, etc */
14 # include <mntent.h>
15 #elif HAVE_SYS_UCRED_H
16 /* NetBSD, etc */
17 # include <fstab.h>
18 # include <sys/param.h>
19 # include <sys/ucred.h>
20 # include <sys/mount.h>
21 # include <stdlib.h>
22 #endif
23 #include <sys/stat.h>
24 #include <sys/time.h>
25 #include <unistd.h>
27 #include <glib.h>
28 #include <gtk/gtk.h>
30 #include "mount.h"
32 /* Map mount points to mntent structures */
33 GHashTable *fstab_mounts = NULL;
34 GHashTable *mtab_mounts = NULL;
35 time_t fstab_time;
36 #ifdef HAVE_MNTENT_H
37 time_t mtab_time;
38 #endif
40 /* Static prototypes */
41 #ifdef HAVE_SYS_UCRED_H
42 static GHashTable *build_mtab_table(GHashTable *mount_points);
43 #endif
44 #ifdef DO_MOUNT_POINTS
45 static GHashTable *read_table(GHashTable *mount_points, char *path);
46 static void clear_table(GHashTable *table);
47 static time_t read_time(char *path);
48 static gboolean free_mp(gpointer key, gpointer value, gpointer data);
49 #endif
51 void mount_init()
53 fstab_mounts = g_hash_table_new(g_str_hash, g_str_equal);
54 mtab_mounts = g_hash_table_new(g_str_hash, g_str_equal);
56 #ifdef DO_MOUNT_POINTS
57 fstab_time = read_time("/etc/fstab");
58 read_table(fstab_mounts, "/etc/fstab");
59 # ifdef HAVE_MNTENT_H
60 mtab_time = read_time("/etc/mtab");
61 read_table(mtab_mounts, "/etc/mtab");
62 # elif HAVE_SYS_UCRED_H
63 /* mtab_time not used */
64 build_mtab_table(mtab_mounts);
65 # endif
66 #endif /* DO_MOUNT_POINTS */
69 void mount_update()
71 #ifdef DO_MOUNT_POINTS
72 time_t time;
73 /* Ensure everything is uptodate */
75 time = read_time("/etc/fstab");
76 if (time != fstab_time)
78 fstab_time = time;
79 read_table(fstab_mounts, "/etc/fstab");
81 # ifdef HAVE_MNTENT_H
82 time = read_time("/etc/mtab");
83 if (time != mtab_time)
85 mtab_time = time;
86 read_table(mtab_mounts, "/etc/mtab");
88 # else
89 build_mtab_table(mtab_mounts);
90 # endif
91 #endif /* DO_MOUNT_POINTS */
95 #ifdef DO_MOUNT_POINTS
97 static gboolean free_mp(gpointer key, gpointer value, gpointer data)
99 MountPoint *mp = (MountPoint *) value;
101 g_free(mp->name);
102 g_free(mp->dir);
103 g_free(mp);
105 return TRUE;
108 /* Remove all entries from a hash table, freeing them as we go */
109 static void clear_table(GHashTable *table)
111 g_hash_table_foreach_remove(table, free_mp, NULL);
114 /* Return the mtime of a file */
115 static time_t read_time(char *path)
117 struct stat info;
119 g_return_val_if_fail(stat(path, &info) == 0, 0);
121 return info.st_mtime;
124 #endif
126 #ifdef HAVE_MNTENT_H
127 static GHashTable *read_table(GHashTable *mount_points, char *path)
129 FILE *tab;
130 struct mntent *ent;
131 MountPoint *mp;
133 clear_table(mount_points);
135 tab = setmntent(path, "r");
136 g_return_val_if_fail(tab != NULL, NULL);
138 while ((ent = getmntent(tab)))
140 if (strcmp(ent->mnt_dir, "swap") == 0)
141 continue;
143 mp = g_malloc(sizeof(MountPoint));
144 mp->name = g_strdup(ent->mnt_fsname);
145 mp->dir = g_strdup(ent->mnt_dir);
147 g_hash_table_insert(mount_points, mp->dir, mp);
150 endmntent(tab);
152 return mount_points;
155 #elif HAVE_SYS_UCRED_H /* We don't have /etc/mtab */
157 static GHashTable *read_table(GHashTable *mount_points, char *path)
159 int tab;
160 struct fstab *ent;
161 MountPoint *mp;
163 clear_table(mount_points);
165 tab = setfsent();
166 g_return_val_if_fail(tab != 0, NULL);
168 while ((ent = getfsent()))
170 if (strcmp(ent->fs_vfstype, "swap") == 0)
171 continue;
172 if (strcmp(ent->fs_vfstype, "kernfs") == 0)
173 continue;
175 mp = g_malloc(sizeof(MountPoint));
176 mp->name = g_strdup(ent->fs_spec); /* block special device name */
177 mp->dir = g_strdup(ent->fs_file); /* file system path prefix */
179 g_hash_table_insert(mount_points, mp->dir, mp);
182 endfsent();
184 return mount_points;
188 /* build table of mounted file systems */
189 static GHashTable *build_mtab_table(GHashTable *mount_points)
191 int fsstat_index;
192 int fsstat_entries;
193 struct statfs *mntbufp;
194 MountPoint *mp;
196 clear_table( mount_points);
198 /* we could use getfsstat twice and do the memory allocation
199 * ourselves, but I feel lazy today. we can't free memory after use
200 * though.
202 fsstat_entries = getmntinfo( &mntbufp, MNT_WAIT);
203 /* wait for mount entries to be updated by each file system.
204 * Use MNT_NOWAIT if you don't want this to block, but results
205 * may not be up to date.
207 g_return_val_if_fail(fsstat_entries >= 0, NULL);
208 if (fsstat_entries == 0) return NULL;
209 /* not a failure but nothing mounted! */
211 for (fsstat_index = 0; fsstat_index < fsstat_entries; fsstat_index++)
213 if(strcmp(mntbufp[fsstat_index].f_fstypename, "swap") == 0)
214 continue;
215 if(strcmp(mntbufp[fsstat_index].f_fstypename, "kernfs") == 0)
216 continue;
218 mp = g_malloc(sizeof(MountPoint));
219 mp->name = g_strdup( mntbufp[fsstat_index].f_mntfromname);
220 mp->dir = g_strdup( mntbufp[fsstat_index].f_mntonname);
222 g_hash_table_insert(mount_points, mp->dir, mp);
225 return mount_points;
228 #endif