1/*	$NetBSD$	*/
2
3/*
4 * Copyright (c) 1997-2009 Erez Zadok
5 * Copyright (c) 1990 Jan-Simon Pendry
6 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
7 * Copyright (c) 1990 The Regents of the University of California.
8 * All rights reserved.
9 *
10 * This code is derived from software contributed to Berkeley by
11 * Jan-Simon Pendry at Imperial College, London.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 *    must display the following acknowledgment:
23 *      This product includes software developed by the University of
24 *      California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 *    may be used to endorse or promote products derived from this software
27 *    without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
40 *
41 *
42 * File: am-utils/conf/mtab/mtab_aix.c
43 *
44 */
45
46/*
47 * AIX systems don't write their mount tables on a file.  Instead, they
48 * use a (better) system where the kernel keeps this state, and you access
49 * the mount tables via a known interface.
50 */
51
52#ifdef HAVE_CONFIG_H
53# include <config.h>
54#endif /* HAVE_CONFIG_H */
55#include <am_defs.h>
56#include <amu.h>
57
58/*
59 * These were missing external definitions from old AIX's headers.  They
60 * appear to be available in <sys/vmount.h> on AIX 5.3, and possibly
61 * earlier. Hence I commented this out.
62 */
63#ifndef HAVE_EXTERN_MNTCTL
64extern int mntctl(int cmd, int size, voidp buf);
65#endif /* not HAVE_EXTERN_MNTCTL */
66
67
68static mntent_t *
69mnt_dup(struct vmount *mp)
70{
71  mntent_t *new_mp = ALLOC(mntent_t);
72  char *ty;
73  char *fsname = strdup(vmt2dataptr(mp, VMT_OBJECT));
74
75  new_mp->mnt_dir = strdup(vmt2dataptr(mp, VMT_STUB));
76  new_mp->mnt_opts = strdup(vmt2dataptr(mp, VMT_ARGS));
77
78  switch (mp->vmt_gfstype) {
79
80  case MOUNT_TYPE_UFS:
81    ty = MNTTAB_TYPE_UFS;
82    new_mp->mnt_fsname = strdup(fsname);
83    break;
84
85  case MOUNT_TYPE_NFS:
86    ty = MNTTAB_TYPE_NFS;
87    new_mp->mnt_fsname = str3cat((char *) NULL,
88				 vmt2dataptr(mp, VMT_HOSTNAME), ":",
89				 fsname);
90    break;
91
92#ifdef HAVE_FS_NFS3
93  case MOUNT_TYPE_NFS3:
94    ty = MNTTAB_TYPE_NFS3;
95    new_mp->mnt_fsname = str3cat((char *) NULL,
96				 vmt2dataptr(mp, VMT_HOSTNAME), ":",
97				 fsname);
98    break;
99#endif /* HAVE_FS_NFS3 */
100
101  default:
102    ty = "unknown";
103    new_mp->mnt_fsname = strdup(fsname);
104    break;
105
106  }
107
108  new_mp->mnt_type = strdup(ty);
109  /* store the VFS ID for uvmount() */
110  new_mp->mnt_passno = mp->vmt_vfsnumber;
111  new_mp->mnt_freq = 0;
112
113  XFREE(fsname);
114
115  return new_mp;
116}
117
118
119/*
120 * Read a mount table into memory
121 */
122mntlist *
123read_mtab(char *fs, const char *mnttabname)
124{
125  mntlist **mpp, *mhp;
126  int i;
127  char *mntinfo = NULL, *cp;
128  struct vmount *vp;
129  int ret;
130  int maxtry = 10;		/* maximum number of times to try mntctl */
131
132  /*
133   * Figure out size of mount table and allocate space for a copy.  Then get
134   * mount table for real.  We repeat this loop at most 10 times to minimze
135   * the chance of a race condition (something gets un/mounted in between
136   * calls to mntctl()
137   */
138  i = sizeof(int);
139  do {
140    if (mntinfo)
141      XFREE(mntinfo);
142    mntinfo = xmalloc(i);
143    ret = mntctl(MCTL_QUERY, i, mntinfo);
144    if (ret == 0)
145      i = *(int*) mntinfo;
146    if (--maxtry <= 0) {
147      plog(XLOG_ERROR, "mntctl: could not get a stable result");
148      ret = -1;
149      errno = EINVAL;
150      break;
151    }
152  } while (ret == 0);
153  if (ret < 0) {
154    plog(XLOG_ERROR, "mntctl: %m");
155    goto out;
156  }
157
158  mpp = &mhp;
159  for (i = 0, cp = mntinfo; i < ret; i++, cp += vp->vmt_length) {
160    vp = (struct vmount *) cp;
161
162    /*
163     * Allocate a new slot
164     */
165    *mpp = ALLOC(struct mntlist);
166
167    /*
168     * Copy the data returned by mntctl
169     */
170    (*mpp)->mnt = mnt_dup(vp);
171
172    /*
173     * Move to next pointer
174     */
175    mpp = &(*mpp)->mnext;
176  }
177
178  *mpp = NULL;
179
180out:
181  if (mntinfo)
182    XFREE(mntinfo);
183  return mhp;
184}
185