4 * ROX-Filer, filer for the ROX desktop project
5 * By Thomas Leonard, <tal197@ecs.soton.ac.uk>.
8 /* mount.c - code for handling mount points */
15 #elif HAVE_SYS_UCRED_H
18 # include <sys/param.h>
19 # include <sys/ucred.h>
20 # include <sys/mount.h>
32 /* Map mount points to mntent structures */
33 GHashTable
*fstab_mounts
= NULL
;
34 GHashTable
*mtab_mounts
= NULL
;
40 /* Static prototypes */
41 #ifdef HAVE_SYS_UCRED_H
42 static GHashTable
*build_mtab_table(GHashTable
*mount_points
);
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
);
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");
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
);
66 #endif /* DO_MOUNT_POINTS */
71 #ifdef DO_MOUNT_POINTS
73 /* Ensure everything is uptodate */
75 time
= read_time("/etc/fstab");
76 if (time
!= fstab_time
)
79 read_table(fstab_mounts
, "/etc/fstab");
82 time
= read_time("/etc/mtab");
83 if (time
!= mtab_time
)
86 read_table(mtab_mounts
, "/etc/mtab");
89 build_mtab_table(mtab_mounts
);
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
;
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
)
119 g_return_val_if_fail(stat(path
, &info
) == 0, 0);
121 return info
.st_mtime
;
127 static GHashTable
*read_table(GHashTable
*mount_points
, char *path
)
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)
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
);
155 #elif HAVE_SYS_UCRED_H /* We don't have /etc/mtab */
157 static GHashTable
*read_table(GHashTable
*mount_points
, char *path
)
163 clear_table(mount_points
);
166 g_return_val_if_fail(tab
!= 0, NULL
);
168 while ((ent
= getfsent()))
170 if (strcmp(ent
->fs_vfstype
, "swap") == 0)
172 if (strcmp(ent
->fs_vfstype
, "kernfs") == 0)
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
);
188 /* build table of mounted file systems */
189 static GHashTable
*build_mtab_table(GHashTable
*mount_points
)
193 struct statfs
*mntbufp
;
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
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)
215 if(strcmp(mntbufp
[fsstat_index
].f_fstypename
, "kernfs") == 0)
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
);