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)
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
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 */
32 #elif HAVE_SYS_UCRED_H
35 # include <sys/param.h>
36 # include <sys/ucred.h>
37 # include <sys/mount.h>
39 #elif HAVE_SYS_MNTENT_H
41 # include <sys/mntent.h>
42 # include <sys/mnttab.h>
52 /* Map mount points to mntent structures */
53 GHashTable
*fstab_mounts
= NULL
;
54 GHashTable
*mtab_mounts
= NULL
;
57 #ifdef HAVE_SYS_MNTENT_H
58 #define THE_MTAB MNTTAB
59 #define THE_FSTAB VFSTAB
61 #define THE_MTAB "/etc/mtab"
62 #define THE_FSTAB "/etc/fstab"
65 #if defined(HAVE_MNTENT_H) || defined(HAVE_SYS_MNTENT_H)
69 /* Static prototypes */
70 #ifdef HAVE_SYS_UCRED_H
71 static GHashTable
*build_mtab_table(GHashTable
*mount_points
);
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
);
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
);
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
103 /* Ensure everything is uptodate */
105 time
= read_time(THE_FSTAB
);
106 if (force
|| time
!= fstab_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
)
116 read_table(mtab_mounts
, THE_MTAB
);
119 build_mtab_table(mtab_mounts
);
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
;
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
)
149 g_return_val_if_fail(stat(path
, &info
) == 0, 0);
151 return info
.st_mtime
;
157 static GHashTable
*read_table(GHashTable
*mount_points
, char *path
)
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)
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
);
185 #elif HAVE_SYS_MNTENT_H
186 static GHashTable
*read_table(GHashTable
*mount_points
, char *path
)
195 tab
= fopen(path
, "r");
196 g_return_val_if_fail(tab
!= NULL
, NULL
);
197 clear_table(mount_points
);
204 fcntl(fileno(tab
), F_SETLKW
, &lb
);
207 while (getmntent(tab
, &ent
)==0)
209 if (strcmp(ent
.mnt_special
, "swap") == 0)
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
);
224 #elif HAVE_SYS_UCRED_H /* We don't have /etc/mtab */
226 static GHashTable
*read_table(GHashTable
*mount_points
, char *path
)
232 clear_table(mount_points
);
235 g_return_val_if_fail(tab
!= 0, NULL
);
237 while ((ent
= getfsent()))
239 if (strcmp(ent
->fs_vfstype
, "swap") == 0)
241 if (strcmp(ent
->fs_vfstype
, "kernfs") == 0)
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
);
257 /* build table of mounted file systems */
258 static GHashTable
*build_mtab_table(GHashTable
*mount_points
)
262 struct statfs
*mntbufp
;
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
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)
284 if(strcmp(mntbufp
[fsstat_index
].f_fstypename
, "kernfs") == 0)
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
);