r183: Added the TODO file. Info permissions are displayed in symbolic form.
[rox-filer.git] / ROX-Filer / src / mount.c
blob9d45adfc9aba64c48a3a2b9ea2e5fd837c5b3fa8
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 1999, 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_MNTENT_H
27 /* Linux, etc */
28 # include <mntent.h>
29 #elif HAVE_SYS_UCRED_H
30 /* NetBSD, etc */
31 # include <fstab.h>
32 # include <sys/param.h>
33 # include <sys/ucred.h>
34 # include <sys/mount.h>
35 # include <stdlib.h>
36 #endif
37 #include <sys/stat.h>
38 #include <sys/time.h>
39 #include <unistd.h>
41 #include <glib.h>
42 #include <gtk/gtk.h>
44 #include "mount.h"
46 /* Map mount points to mntent structures */
47 GHashTable *fstab_mounts = NULL;
48 GHashTable *mtab_mounts = NULL;
49 time_t fstab_time;
50 #ifdef HAVE_MNTENT_H
51 time_t mtab_time;
52 #endif
54 /* Static prototypes */
55 #ifdef HAVE_SYS_UCRED_H
56 static GHashTable *build_mtab_table(GHashTable *mount_points);
57 #endif
58 #ifdef DO_MOUNT_POINTS
59 static GHashTable *read_table(GHashTable *mount_points, char *path);
60 static void clear_table(GHashTable *table);
61 static time_t read_time(char *path);
62 static gboolean free_mp(gpointer key, gpointer value, gpointer data);
63 #endif
65 void mount_init()
67 fstab_mounts = g_hash_table_new(g_str_hash, g_str_equal);
68 mtab_mounts = g_hash_table_new(g_str_hash, g_str_equal);
70 #ifdef DO_MOUNT_POINTS
71 fstab_time = read_time("/etc/fstab");
72 read_table(fstab_mounts, "/etc/fstab");
73 # ifdef HAVE_MNTENT_H
74 mtab_time = read_time("/etc/mtab");
75 read_table(mtab_mounts, "/etc/mtab");
76 # elif HAVE_SYS_UCRED_H
77 /* mtab_time not used */
78 build_mtab_table(mtab_mounts);
79 # endif
80 #endif /* DO_MOUNT_POINTS */
83 /* If force is true then ignore the timestamps */
84 void mount_update(gboolean force)
86 #ifdef DO_MOUNT_POINTS
87 time_t time;
88 /* Ensure everything is uptodate */
90 time = read_time("/etc/fstab");
91 if (force || time != fstab_time)
93 fstab_time = time;
94 read_table(fstab_mounts, "/etc/fstab");
96 # ifdef HAVE_MNTENT_H
97 time = read_time("/etc/mtab");
98 if (force || time != mtab_time)
100 mtab_time = time;
101 read_table(mtab_mounts, "/etc/mtab");
103 # else
104 build_mtab_table(mtab_mounts);
105 # endif
106 #endif /* DO_MOUNT_POINTS */
110 #ifdef DO_MOUNT_POINTS
112 static gboolean free_mp(gpointer key, gpointer value, gpointer data)
114 MountPoint *mp = (MountPoint *) value;
116 g_free(mp->name);
117 g_free(mp->dir);
118 g_free(mp);
120 return TRUE;
123 /* Remove all entries from a hash table, freeing them as we go */
124 static void clear_table(GHashTable *table)
126 g_hash_table_foreach_remove(table, free_mp, NULL);
129 /* Return the mtime of a file */
130 static time_t read_time(char *path)
132 struct stat info;
134 g_return_val_if_fail(stat(path, &info) == 0, 0);
136 return info.st_mtime;
139 #endif
141 #ifdef HAVE_MNTENT_H
142 static GHashTable *read_table(GHashTable *mount_points, char *path)
144 FILE *tab;
145 struct mntent *ent;
146 MountPoint *mp;
148 clear_table(mount_points);
150 tab = setmntent(path, "r");
151 g_return_val_if_fail(tab != NULL, NULL);
153 while ((ent = getmntent(tab)))
155 if (strcmp(ent->mnt_dir, "swap") == 0)
156 continue;
158 mp = g_malloc(sizeof(MountPoint));
159 mp->name = g_strdup(ent->mnt_fsname);
160 mp->dir = g_strdup(ent->mnt_dir);
162 g_hash_table_insert(mount_points, mp->dir, mp);
165 endmntent(tab);
167 return mount_points;
170 #elif HAVE_SYS_UCRED_H /* We don't have /etc/mtab */
172 static GHashTable *read_table(GHashTable *mount_points, char *path)
174 int tab;
175 struct fstab *ent;
176 MountPoint *mp;
178 clear_table(mount_points);
180 tab = setfsent();
181 g_return_val_if_fail(tab != 0, NULL);
183 while ((ent = getfsent()))
185 if (strcmp(ent->fs_vfstype, "swap") == 0)
186 continue;
187 if (strcmp(ent->fs_vfstype, "kernfs") == 0)
188 continue;
190 mp = g_malloc(sizeof(MountPoint));
191 mp->name = g_strdup(ent->fs_spec); /* block special device name */
192 mp->dir = g_strdup(ent->fs_file); /* file system path prefix */
194 g_hash_table_insert(mount_points, mp->dir, mp);
197 endfsent();
199 return mount_points;
203 /* build table of mounted file systems */
204 static GHashTable *build_mtab_table(GHashTable *mount_points)
206 int fsstat_index;
207 int fsstat_entries;
208 struct statfs *mntbufp;
209 MountPoint *mp;
211 clear_table( mount_points);
213 /* we could use getfsstat twice and do the memory allocation
214 * ourselves, but I feel lazy today. we can't free memory after use
215 * though.
217 fsstat_entries = getmntinfo( &mntbufp, MNT_WAIT);
218 /* wait for mount entries to be updated by each file system.
219 * Use MNT_NOWAIT if you don't want this to block, but results
220 * may not be up to date.
222 g_return_val_if_fail(fsstat_entries >= 0, NULL);
223 if (fsstat_entries == 0) return NULL;
224 /* not a failure but nothing mounted! */
226 for (fsstat_index = 0; fsstat_index < fsstat_entries; fsstat_index++)
228 if(strcmp(mntbufp[fsstat_index].f_fstypename, "swap") == 0)
229 continue;
230 if(strcmp(mntbufp[fsstat_index].f_fstypename, "kernfs") == 0)
231 continue;
233 mp = g_malloc(sizeof(MountPoint));
234 mp->name = g_strdup( mntbufp[fsstat_index].f_mntfromname);
235 mp->dir = g_strdup( mntbufp[fsstat_index].f_mntonname);
237 g_hash_table_insert(mount_points, mp->dir, mp);
240 return mount_points;
243 #endif