r339: The menu key bindings are now only saved if they actually changed.
[rox-filer/ma.git] / ROX-Filer / src / mount.c
blob2a0f2cbf7a859970fc1eeece674472e78a7e4f16
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2000, Thomas Leonard, <tal197@users.sourceforge.net>.
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/time.h>
46 #include <gtk/gtk.h>
48 #include "global.h"
50 #include "mount.h"
52 /* Map mount points to mntent structures */
53 GHashTable *fstab_mounts = NULL;
54 GHashTable *mtab_mounts = NULL;
55 time_t fstab_time;
57 #ifdef HAVE_SYS_MNTENT_H
58 #define THE_MTAB MNTTAB
59 #define THE_FSTAB VFSTAB
60 #else
61 #define THE_MTAB "/etc/mtab"
62 #define THE_FSTAB "/etc/fstab"
63 #endif
65 #if defined(HAVE_MNTENT_H) || defined(HAVE_SYS_MNTENT_H)
66 time_t mtab_time;
67 #endif
69 /* Static prototypes */
70 #ifdef HAVE_SYS_UCRED_H
71 static GHashTable *build_mtab_table(GHashTable *mount_points);
72 #endif
73 #ifdef DO_MOUNT_POINTS
74 static GHashTable *read_table(GHashTable *mount_points, char *path);
75 static void clear_table(GHashTable *table);
76 static time_t read_time(char *path);
77 static gboolean free_mp(gpointer key, gpointer value, gpointer data);
78 #endif
80 void mount_init()
82 fstab_mounts = g_hash_table_new(g_str_hash, g_str_equal);
83 mtab_mounts = g_hash_table_new(g_str_hash, g_str_equal);
85 #ifdef DO_MOUNT_POINTS
86 fstab_time = read_time(THE_FSTAB);
87 read_table(fstab_mounts, THE_FSTAB);
88 # if defined(HAVE_MNTENT_H) || defined(HAVE_SYS_MNTENT_H)
89 mtab_time = read_time(THE_MTAB);
90 read_table(mtab_mounts, THE_MTAB);
91 # elif HAVE_SYS_UCRED_H
92 /* mtab_time not used */
93 build_mtab_table(mtab_mounts);
94 # endif
95 #endif /* DO_MOUNT_POINTS */
98 /* If force is true then ignore the timestamps */
99 void mount_update(gboolean force)
101 #ifdef DO_MOUNT_POINTS
102 time_t time;
103 /* Ensure everything is uptodate */
105 time = read_time(THE_FSTAB);
106 if (force || time != fstab_time)
108 fstab_time = time;
109 read_table(fstab_mounts, THE_FSTAB);
111 # if defined(HAVE_MNTENT_H) || defined(HAVE_SYS_MNTENT_H)
112 time = read_time(THE_MTAB);
113 if (force || time != mtab_time)
115 mtab_time = time;
116 read_table(mtab_mounts, THE_MTAB);
118 # else
119 build_mtab_table(mtab_mounts);
120 # endif
121 #endif /* DO_MOUNT_POINTS */
125 #ifdef DO_MOUNT_POINTS
127 static gboolean free_mp(gpointer key, gpointer value, gpointer data)
129 MountPoint *mp = (MountPoint *) value;
131 g_free(mp->name);
132 g_free(mp->dir);
133 g_free(mp);
135 return TRUE;
138 /* Remove all entries from a hash table, freeing them as we go */
139 static void clear_table(GHashTable *table)
141 g_hash_table_foreach_remove(table, free_mp, NULL);
144 /* Return the mtime of a file */
145 static time_t read_time(char *path)
147 struct stat info;
149 g_return_val_if_fail(stat(path, &info) == 0, 0);
151 return info.st_mtime;
154 #endif
156 #ifdef HAVE_MNTENT_H
157 static GHashTable *read_table(GHashTable *mount_points, char *path)
159 FILE *tab;
160 struct mntent *ent;
161 MountPoint *mp;
163 clear_table(mount_points);
165 tab = setmntent(path, "r");
166 g_return_val_if_fail(tab != NULL, NULL);
168 while ((ent = getmntent(tab)))
170 if (strcmp(ent->mnt_dir, "swap") == 0)
171 continue;
173 mp = g_malloc(sizeof(MountPoint));
174 mp->name = g_strdup(ent->mnt_fsname);
175 mp->dir = g_strdup(ent->mnt_dir);
177 g_hash_table_insert(mount_points, mp->dir, mp);
180 endmntent(tab);
182 return mount_points;
185 #elif HAVE_SYS_MNTENT_H
186 static GHashTable *read_table(GHashTable *mount_points, char *path)
188 FILE *tab;
189 struct mnttab ent;
190 MountPoint *mp;
191 #ifdef HAVE_FCNTL_H
192 struct flock lb;
193 #endif
195 tab = fopen(path, "r");
196 g_return_val_if_fail(tab != NULL, NULL);
197 clear_table(mount_points);
199 #ifdef HAVE_FCNTL_H
200 lb.l_type = F_RDLCK;
201 lb.l_whence = 0;
202 lb.l_start = 0;
203 lb.l_len = 0;
204 fcntl(fileno(tab), F_SETLKW, &lb);
205 #endif
207 while (getmntent(tab, &ent)==0)
209 if (strcmp(ent.mnt_special, "swap") == 0)
210 continue;
212 mp = g_malloc(sizeof(MountPoint));
213 mp->dir = g_strdup(ent.mnt_mountp);
214 mp->name = g_strdup(ent.mnt_special);
216 g_hash_table_insert(mount_points, mp->dir, mp);
219 fclose(tab);
221 return mount_points;
224 #elif HAVE_SYS_UCRED_H /* We don't have /etc/mtab */
226 static GHashTable *read_table(GHashTable *mount_points, char *path)
228 int tab;
229 struct fstab *ent;
230 MountPoint *mp;
232 clear_table(mount_points);
234 tab = setfsent();
235 g_return_val_if_fail(tab != 0, NULL);
237 while ((ent = getfsent()))
239 if (strcmp(ent->fs_vfstype, "swap") == 0)
240 continue;
241 if (strcmp(ent->fs_vfstype, "kernfs") == 0)
242 continue;
244 mp = g_malloc(sizeof(MountPoint));
245 mp->name = g_strdup(ent->fs_spec); /* block special device name */
246 mp->dir = g_strdup(ent->fs_file); /* file system path prefix */
248 g_hash_table_insert(mount_points, mp->dir, mp);
251 endfsent();
253 return mount_points;
257 /* build table of mounted file systems */
258 static GHashTable *build_mtab_table(GHashTable *mount_points)
260 int fsstat_index;
261 int fsstat_entries;
262 struct statfs *mntbufp;
263 MountPoint *mp;
265 clear_table( mount_points);
267 /* we could use getfsstat twice and do the memory allocation
268 * ourselves, but I feel lazy today. we can't free memory after use
269 * though.
271 fsstat_entries = getmntinfo( &mntbufp, MNT_WAIT);
272 /* wait for mount entries to be updated by each file system.
273 * Use MNT_NOWAIT if you don't want this to block, but results
274 * may not be up to date.
276 g_return_val_if_fail(fsstat_entries >= 0, NULL);
277 if (fsstat_entries == 0) return NULL;
278 /* not a failure but nothing mounted! */
280 for (fsstat_index = 0; fsstat_index < fsstat_entries; fsstat_index++)
282 if(strcmp(mntbufp[fsstat_index].f_fstypename, "swap") == 0)
283 continue;
284 if(strcmp(mntbufp[fsstat_index].f_fstypename, "kernfs") == 0)
285 continue;
287 mp = g_malloc(sizeof(MountPoint));
288 mp->name = g_strdup( mntbufp[fsstat_index].f_mntfromname);
289 mp->dir = g_strdup( mntbufp[fsstat_index].f_mntonname);
291 g_hash_table_insert(mount_points, mp->dir, mp);
294 return mount_points;
297 #endif