* Authors:
* Jonathan Pryor (jonpryor@vt.edu)
*
- * Copyright (C) 2004 Jonathan Pryor
+ * Copyright (C) 2004-2005 Jonathan Pryor
*/
-#include <fstab.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stddef.h>
+#include "map.h"
#include "mph.h"
+#if defined (HAVE_CHECKLIST_H)
+#include <checklist.h>
+#elif defined (HAVE_FSTAB_H)
+#include <fstab.h>
+#endif /* def HAVE_FSTAB_H */
+
+#ifdef HAVE_SYS_VFSTAB_H
+#include <sys/vfstab.h>
+#endif /* def HAVE_SYS_VFSTAB_H */
+
G_BEGIN_DECLS
-struct Mono_Posix_Syscall__Fstab {
- char *fs_spec; /* block device name */
- char *fs_file; /* mount point */
- char *fs_vfstype; /* filesystem type */
- char *fs_mntops; /* mount options */
- char *fs_type; /* rw/rq/ro/sw/xx option */
- int fs_freq; /* dump frequency, in days */
- int fs_passno; /* pass number on parallel dump */
+#ifdef HAVE_CHECKLIST_H
+
+typedef struct checklist mph_fstab;
- char *_fs_buf_;
+static const size_t
+fstab_offsets[] = {
+ offsetof (struct checklist, fs_spec),
+ offsetof (struct checklist, fs_dir),
+ offsetof (struct checklist, fs_type)
};
+static const size_t
+mph_fstab_offsets[] = {
+ offsetof (struct Mono_Posix_Syscall__Fstab, fs_spec),
+ offsetof (struct Mono_Posix_Syscall__Fstab, fs_file),
+ offsetof (struct Mono_Posix_Syscall__Fstab, fs_type)
+};
+
+#elif defined (HAVE_FSTAB_H)
+
+typedef struct fstab mph_fstab;
+
static const size_t
fstab_offsets[] = {
offsetof (struct fstab, fs_spec),
offsetof (struct Mono_Posix_Syscall__Fstab, fs_type)
};
+#endif /* def HAVE_FSTAB_H */
+
+#if defined (HAVE_CHECKLIST_H) || defined (HAVE_FSTAB_H)
+
/*
- * Copy the native `passwd' structure to it's managed representation.
+ * Copy the native `fstab' structure to it's managed representation.
*
* To minimize separate mallocs, all the strings are allocated within the same
* memory block (stored in _fs_buf_).
*/
static int
-copy_fstab (struct Mono_Posix_Syscall__Fstab *to, struct fstab *from)
+copy_fstab (struct Mono_Posix_Syscall__Fstab *to, mph_fstab *from)
{
char *buf;
+
+ memset (to, 0, sizeof(*to));
+
buf = _mph_copy_structure_strings (to, mph_fstab_offsets,
from, fstab_offsets, sizeof(fstab_offsets)/sizeof(fstab_offsets[0]));
return 0;
}
+#endif /* def HAVE_CHECKLIST_H || def HAVE_FSTAB_H */
+
+#ifdef HAVE_SYS_VFSTAB_H
+
+/*
+ * Solaris doesn't provide <fstab.h> but has equivalent functionality in
+ * <sys/fstab.h> via getvfsent(3C) and company.
+ */
+
+typedef struct vfstab mph_fstab;
+
+static const size_t
+vfstab_offsets[] = {
+ offsetof (struct vfstab, vfs_special),
+ offsetof (struct vfstab, vfs_mountp),
+ offsetof (struct vfstab, vfs_fstype),
+ offsetof (struct vfstab, vfs_mntopts)
+};
+
+static const size_t
+mph_fstab_offsets[] = {
+ offsetof (struct Mono_Posix_Syscall__Fstab, fs_spec),
+ offsetof (struct Mono_Posix_Syscall__Fstab, fs_file),
+ offsetof (struct Mono_Posix_Syscall__Fstab, fs_vfstype),
+ offsetof (struct Mono_Posix_Syscall__Fstab, fs_mntops)
+};
+
+/*
+ * Copy the native `vfstab' structure to it's managed representation.
+ *
+ * To minimize separate mallocs, all the strings are allocated within the same
+ * memory block (stored in _fs_buf_).
+ */
+static int
+copy_fstab (struct Mono_Posix_Syscall__Fstab *to, struct vfstab *from)
+{
+ char *buf;
+
+ memset (to, 0, sizeof(*to));
+
+ buf = _mph_copy_structure_strings (to, mph_fstab_offsets,
+ from, vfstab_offsets, sizeof(vfstab_offsets)/sizeof(vfstab_offsets[0]));
+
+ to->fs_type = NULL;
+ to->fs_freq = -1;
+ to->fs_passno = -1;
+
+ to->_fs_buf_ = buf;
+ if (buf == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Implement Linux/BSD getfsent(3) in terms of Solaris getvfsent(3C)...
+ */
+static FILE*
+etc_fstab;
+
+static int
+setfsent (void)
+{
+ /* protect from bad users calling setfsent(), setfsent(), ... endfsent() */
+ if (etc_fstab != NULL)
+ fclose (etc_fstab);
+ etc_fstab = fopen ("/etc/vfstab", "r");
+ if (etc_fstab != NULL)
+ return 1;
+ return 0;
+}
+
+static void
+endfsent (void)
+{
+ fclose (etc_fstab);
+ etc_fstab = NULL;
+}
+
+static struct vfstab
+cur_vfstab_entry;
+
+static struct vfstab*
+getfsent (void)
+{
+ int r;
+ r = getvfsent (etc_fstab, &cur_vfstab_entry);
+ if (r == 0)
+ return &cur_vfstab_entry;
+ return NULL;
+}
+
+static struct vfstab*
+getfsfile (const char *mount_point)
+{
+ int r;
+ int close = 0;
+ if (etc_fstab == 0) {
+ close = 1;
+ if (setfsent () != 1)
+ return NULL;
+ }
+ rewind (etc_fstab);
+ r = getvfsfile (etc_fstab, &cur_vfstab_entry, (char*) mount_point);
+ if (close)
+ endfsent ();
+ if (r == 0)
+ return &cur_vfstab_entry;
+ return NULL;
+}
+
+static struct vfstab*
+getfsspec (const char *special_file)
+{
+ int r;
+ int close = 0;
+ if (etc_fstab == 0) {
+ close = 1;
+ if (setfsent () != 1)
+ return NULL;
+ }
+ rewind (etc_fstab);
+ r = getvfsspec (etc_fstab, &cur_vfstab_entry, (char*) special_file);
+ if (close)
+ endfsent ();
+ if (r == 0)
+ return &cur_vfstab_entry;
+ return NULL;
+}
+
+#endif /* def HAVE_SYS_VFSTAB_H */
+
+#if defined (HAVE_FSTAB_H) || defined (HAVE_CHECKPOINT_H) || defined (HAVE_SYS_VFSTAB_H)
+
+int
+Mono_Posix_Syscall_endfsent (void)
+{
+ endfsent ();
+ return 0;
+}
+
gint32
Mono_Posix_Syscall_getfsent (struct Mono_Posix_Syscall__Fstab *fsbuf)
{
- struct fstab *fs;
+ mph_fstab *fs;
if (fsbuf == NULL) {
errno = EFAULT;
Mono_Posix_Syscall_getfsfile (const char *mount_point,
struct Mono_Posix_Syscall__Fstab *fsbuf)
{
- struct fstab *fs;
+ mph_fstab *fs;
if (fsbuf == NULL) {
errno = EFAULT;
Mono_Posix_Syscall_getfsspec (const char *special_file,
struct Mono_Posix_Syscall__Fstab *fsbuf)
{
- struct fstab *fs;
+ mph_fstab *fs;
if (fsbuf == NULL) {
errno = EFAULT;
return 0;
}
+gint32
+Mono_Posix_Syscall_setfsent (void)
+{
+ return setfsent ();
+}
+
+#endif /* def HAVE_FSTAB_H || def HAVE_CHECKPOINT_H || def HAVE_SYS_VFSTAB_H */
+
G_END_DECLS
/*