r228: Added a nice list displaying the found files. Clicking opens a preview window
[rox-filer.git] / ROX-Filer / src / mount.c
blobb57f041697244804afc68a588cf87e860fae3a75
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2000, Thomas Leonard, <tal197@ecs.soton.ac.uk>.
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 #ifdef HAVE_FCNTL_H
27 #include <fcntl.h>
28 #endif
29 #ifdef HAVE_MNTENT_H
30 /* Linux, etc */
31 # include <mntent.h>
32 #elif HAVE_SYS_UCRED_H
33 /* NetBSD, etc */
34 # include <fstab.h>
35 # include <sys/param.h>
36 # include <sys/ucred.h>
37 # include <sys/mount.h>
38 # include <stdlib.h>
39 #elif HAVE_SYS_MNTENT_H
40 /* SunOS */
41 # include <sys/mntent.h>
42 # include <sys/mnttab.h>
43 #endif
44 #include <sys/stat.h>
45 #include <sys/time.h>
46 #include <unistd.h>
48 #include <glib.h>
49 #include <gtk/gtk.h>
51 #include "mount.h"
53 /* Map mount points to mntent structures */
54 GHashTable *fstab_mounts = NULL;
55 GHashTable *mtab_mounts = NULL;
56 time_t fstab_time;
58 #ifdef HAVE_SYS_MNTENT_H
59 #define THE_MTAB MNTTAB
60 #define THE_FSTAB VFSTAB
61 #else
62 #define THE_MTAB "/etc/mtab"
63 #define THE_FSTAB "/etc/fstab"
64 #endif
66 #if defined(HAVE_MNTENT_H) || defined(HAVE_SYS_MNTENT_H)
67 time_t mtab_time;
68 #endif
70 /* Static prototypes */
71 #ifdef HAVE_SYS_UCRED_H
72 static GHashTable *build_mtab_table(GHashTable *mount_points);
73 #endif
74 #ifdef DO_MOUNT_POINTS
75 static GHashTable *read_table(GHashTable *mount_points, char *path);
76 static void clear_table(GHashTable *table);
77 static time_t read_time(char *path);
78 static gboolean free_mp(gpointer key, gpointer value, gpointer data);
79 #endif
81 void mount_init()
83 fstab_mounts = g_hash_table_new(g_str_hash, g_str_equal);
84 mtab_mounts = g_hash_table_new(g_str_hash, g_str_equal);
86 #ifdef DO_MOUNT_POINTS
87 fstab_time = read_time(THE_FSTAB);
88 read_table(fstab_mounts, THE_FSTAB);
89 # if defined(HAVE_MNTENT_H) || defined(HAVE_SYS_MNTENT_H)
90 mtab_time = read_time(THE_MTAB);
91 read_table(mtab_mounts, THE_MTAB);
92 # elif HAVE_SYS_UCRED_H
93 /* mtab_time not used */
94 build_mtab_table(mtab_mounts);
95 # endif
96 #endif /* DO_MOUNT_POINTS */
99 /* If force is true then ignore the timestamps */
100 void mount_update(gboolean force)
102 #ifdef DO_MOUNT_POINTS
103 time_t time;
104 /* Ensure everything is uptodate */
106 time = read_time(THE_FSTAB);
107 if (force || time != fstab_time)
109 fstab_time = time;
110 read_table(fstab_mounts, THE_FSTAB);
112 # if defined(HAVE_MNTENT_H) || defined(HAVE_SYS_MNTENT_H)
113 time = read_time(THE_MTAB);
114 if (force || time != mtab_time)
116 mtab_time = time;
117 read_table(mtab_mounts, THE_MTAB);
119 # else
120 build_mtab_table(mtab_mounts);
121 # endif
122 #endif /* DO_MOUNT_POINTS */
126 #ifdef DO_MOUNT_POINTS
128 static gboolean free_mp(gpointer key, gpointer value, gpointer data)
130 MountPoint *mp = (MountPoint *) value;
132 g_free(mp->name);
133 g_free(mp->dir);
134 g_free(mp);
136 return TRUE;
139 /* Remove all entries from a hash table, freeing them as we go */
140 static void clear_table(GHashTable *table)
142 g_hash_table_foreach_remove(table, free_mp, NULL);
145 /* Return the mtime of a file */
146 static time_t read_time(char *path)
148 struct stat info;
150 g_return_val_if_fail(stat(path, &info) == 0, 0);
152 return info.st_mtime;
155 #endif
157 #ifdef HAVE_MNTENT_H
158 static GHashTable *read_table(GHashTable *mount_points, char *path)
160 FILE *tab;
161 struct mntent *ent;
162 MountPoint *mp;
164 clear_table(mount_points);
166 tab = setmntent(path, "r");
167 g_return_val_if_fail(tab != NULL, NULL);
169 while ((ent = getmntent(tab)))
171 if (strcmp(ent->mnt_dir, "swap") == 0)
172 continue;
174 mp = g_malloc(sizeof(MountPoint));
175 mp->name = g_strdup(ent->mnt_fsname);
176 mp->dir = g_strdup(ent->mnt_dir);
178 g_hash_table_insert(mount_points, mp->dir, mp);
181 endmntent(tab);
183 return mount_points;
186 #elif HAVE_SYS_MNTENT_H
187 static GHashTable *read_table(GHashTable *mount_points, char *path)
189 FILE *tab;
190 struct mnttab ent;
191 MountPoint *mp;
192 #ifdef HAVE_FCNTL_H
193 struct flock lb;
194 #endif
196 tab = fopen(path, "r");
197 g_return_val_if_fail(tab != NULL, NULL);
198 clear_table(mount_points);
200 #ifdef HAVE_FCNTL_H
201 lb.l_type = F_RDLCK;
202 lb.l_whence = 0;
203 lb.l_start = 0;
204 lb.l_len = 0;
205 fcntl(fileno(tab), F_SETLKW, &lb);
206 #endif
208 while (getmntent(tab, &ent)==0)
210 if (strcmp(ent.mnt_special, "swap") == 0)
211 continue;
213 mp = g_malloc(sizeof(MountPoint));
214 mp->dir = g_strdup(ent.mnt_mountp);
215 mp->name = g_strdup(ent.mnt_special);
217 g_hash_table_insert(mount_points, mp->dir, mp);
220 fclose(tab);
222 return mount_points;
225 #elif HAVE_SYS_UCRED_H /* We don't have /etc/mtab */
227 static GHashTable *read_table(GHashTable *mount_points, char *path)
229 int tab;
230 struct fstab *ent;
231 MountPoint *mp;
233 clear_table(mount_points);
235 tab = setfsent();
236 g_return_val_if_fail(tab != 0, NULL);
238 while ((ent = getfsent()))
240 if (strcmp(ent->fs_vfstype, "swap") == 0)
241 continue;
242 if (strcmp(ent->fs_vfstype, "kernfs") == 0)
243 continue;
245 mp = g_malloc(sizeof(MountPoint));
246 mp->name = g_strdup(ent->fs_spec); /* block special device name */
247 mp->dir = g_strdup(ent->fs_file); /* file system path prefix */
249 g_hash_table_insert(mount_points, mp->dir, mp);
252 endfsent();
254 return mount_points;
258 /* build table of mounted file systems */
259 static GHashTable *build_mtab_table(GHashTable *mount_points)
261 int fsstat_index;
262 int fsstat_entries;
263 struct statfs *mntbufp;
264 MountPoint *mp;
266 clear_table( mount_points);
268 /* we could use getfsstat twice and do the memory allocation
269 * ourselves, but I feel lazy today. we can't free memory after use
270 * though.
272 fsstat_entries = getmntinfo( &mntbufp, MNT_WAIT);
273 /* wait for mount entries to be updated by each file system.
274 * Use MNT_NOWAIT if you don't want this to block, but results
275 * may not be up to date.
277 g_return_val_if_fail(fsstat_entries >= 0, NULL);
278 if (fsstat_entries == 0) return NULL;
279 /* not a failure but nothing mounted! */
281 for (fsstat_index = 0; fsstat_index < fsstat_entries; fsstat_index++)
283 if(strcmp(mntbufp[fsstat_index].f_fstypename, "swap") == 0)
284 continue;
285 if(strcmp(mntbufp[fsstat_index].f_fstypename, "kernfs") == 0)
286 continue;
288 mp = g_malloc(sizeof(MountPoint));
289 mp->name = g_strdup( mntbufp[fsstat_index].f_mntfromname);
290 mp->dir = g_strdup( mntbufp[fsstat_index].f_mntonname);
292 g_hash_table_insert(mount_points, mp->dir, mp);
295 return mount_points;
298 #endif