source: trunk/athena/bin/quota/fslist.c @ 13697

Revision 13697, 7.0 KB checked in by rbasch, 25 years ago (diff)
Specify the correct mount table to setmntent().
Line 
1/* Copyright 1999 by the Massachusetts Institute of Technology.
2 *
3 * Permission to use, copy, modify, and distribute this
4 * software and its documentation for any purpose and without
5 * fee is hereby granted, provided that the above copyright
6 * notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting
8 * documentation, and that the name of M.I.T. not be used in
9 * advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission.
11 * M.I.T. makes no representations about the suitability of
12 * this software for any purpose.  It is provided "as is"
13 * without express or implied warranty.
14 */
15
16/* Routines for finding mounted/attached filesystems */
17
18static const char rcsid[] = "$Id: fslist.c,v 1.3 1999-10-07 16:59:29 rbasch Exp $";
19
20/* There are two basic ways of reading the mounted-filesystems table:
21 * the 4.3+BSD way (getfsstat), and the old way (reading a file in
22 * /etc). NetBSD and OSF/1 differ in how you determine the type of
23 * filesystems returned by getfsstat. The non-BSD systems differ in
24 * what the file in /etc is called, and how much of an interface they
25 * provide for reading it. Solaris defines a function getmntent which
26 * is not the same as Irix and Linux's, so we #define around this.
27 */
28
29#include <sys/types.h>
30#include <stdio.h>
31
32#ifdef IRIX
33#include <mntent.h>
34#define MOUNTTAB MOUNTED
35#define GETMNTENT getmntent
36#endif
37
38#ifdef SOLARIS
39#include <sys/mnttab.h>
40
41#define MOUNTTAB MNTTAB
42#define GETMNTENT solaris_compat_getmntent
43#define setmntent fopen
44#define endmntent fclose
45
46struct mntent {
47  char *mnt_fsname;
48  char *mnt_dir;
49  char *mnt_type;
50};
51
52static struct mntent *solaris_compat_getmntent(FILE *);
53#endif
54
55#ifdef LINUX
56#include <mntent.h>
57#define MOUNTTAB _PATH_MOUNTED
58#define GETMNTENT getmntent
59#endif
60
61#ifdef NETBSD
62#include <sys/param.h>
63#include <sys/ucred.h>
64#include <sys/mount.h>
65#define HAVE_GETFSSTAT
66#endif
67
68#ifdef OSF
69#include <sys/types.h>
70#include <sys/mount.h>
71#include <sys/fs_types.h>
72#define HAVE_GETFSSTAT
73#endif
74
75
76#include <errno.h>
77#include <stdlib.h>
78#include <string.h>
79#include <unistd.h>
80
81#include <locker.h>
82#include "quota.h"
83
84extern char **fsnames;
85extern locker_context context;
86
87static int numfs, fssize;
88static int check_fs(locker_context context, locker_attachent *at, void *arg);
89static int add_fs(locker_context context, locker_attachent *at, void *arg);
90static int okname(char *name, char **list);
91
92struct quota_fs *get_fslist(uid_t uid)
93{
94  struct quota_fs *fslist = NULL;
95
96#ifdef HAVE_GETFSSTAT
97
98  struct statfs *mntbuf;
99  int i;
100
101  fssize = getfsstat(NULL, 0, 0);
102  if (fssize)
103    {
104      mntbuf = malloc(fssize * sizeof(struct statfs));
105      if (!mntbuf)
106        {
107          fprintf(stderr, "quota: Out of memory.\n");
108          exit(1);
109        }
110      fssize = getfsstat(mntbuf, fssize * sizeof(struct statfs), MNT_WAIT);
111    }
112  if (!fssize)
113    {
114      fprintf(stderr, "quota: Could not get list of mounted filesystems: %s\n",
115              strerror(errno));
116      exit(1);
117    }
118
119  fslist = malloc(fssize * sizeof(struct quota_fs));
120  if (!fslist)
121    {
122      fprintf(stderr, "quota: Out of memory.\n");
123      exit(1);
124    }
125  memset(fslist, 0, fssize * sizeof(struct quota_fs));
126
127  for (i = numfs = 0; i < fssize; i ++)
128    {
129      if ((
130#ifdef NETBSD
131           !strcmp(mntbuf[i].f_fstypename, "ffs") ||
132           !strcmp(mntbuf[i].f_fstypename, "lfs") ||
133           !strcmp(mntbuf[i].f_fstypename, "nfs")
134#endif
135#ifdef OSF
136           !strcmp(mnt_names[mntbuf[i].f_type], "ufs") ||
137           !strcmp(mnt_names[mntbuf[i].f_type], "nfs")
138#endif
139           ) && okname(mntbuf[i].f_mntonname, fsnames))
140        {
141          fslist[numfs].mount = strdup(mntbuf[i].f_mntonname);
142          fslist[numfs].device = strdup(mntbuf[i].f_mntfromname);
143#ifdef NETBSD
144          fslist[numfs++].type = strdup(mntbuf[i].f_fstypename);
145#endif
146#ifdef OSF
147          fslist[numfs++].type = strdup(mnt_names[mntbuf[i].f_type]);
148#endif
149        }
150    }
151  free(mntbuf);
152
153#else /* HAVE_GETFSSTAT */
154
155  struct mntent *mnt;
156  FILE *mtab;
157
158  mtab = setmntent(MOUNTTAB, "r");
159  while ((mnt = GETMNTENT(mtab)) != NULL)
160    {
161      if ((
162#ifdef IRIX
163           !strcmp(mnt->mnt_type, "xfs") ||
164           !strcmp(mnt->mnt_type, "efs") ||
165#endif
166#ifdef SOLARIS
167           !strcmp(mnt->mnt_type, "ufs") ||
168#endif
169#ifdef LINUX
170           !strcmp(mnt->mnt_type, "e2fs") ||
171#endif
172           !strcmp(mnt->mnt_type, "nfs"))
173          && okname(mnt->mnt_dir, fsnames))
174        {
175          if (numfs == fssize)
176            {
177              fssize = 2 * (fssize + 1);
178              fslist = realloc(fslist, fssize * sizeof(struct quota_fs));
179              if (!fslist)
180                {
181                  fprintf(stderr, "quota: Out of memory.\n");
182                  exit(1);
183                }
184            }
185          memset(&fslist[numfs], 0, sizeof(struct quota_fs));
186          fslist[numfs].device = strdup(mnt->mnt_fsname);
187          fslist[numfs].mount = strdup(mnt->mnt_dir);
188          fslist[numfs++].type = strdup(mnt->mnt_type);
189        }
190    }
191  endmntent(mtab);
192
193#endif /* HAVE_GETFSSTAT */
194
195  /* Now get AFS filesystems, */
196  locker_iterate_attachtab(context, check_fs, uid ? &uid : NULL,
197                           add_fs, &fslist);
198
199  fslist = realloc(fslist, (numfs + 1) * sizeof(struct quota_fs));
200  if (!fslist)
201    {
202      fprintf(stderr, "quota: Out of memory.\n");
203      exit(1);
204    }
205  fslist[numfs].device = fslist[numfs].mount = fslist[numfs].type = NULL;
206
207  return fslist;
208}
209
210/* Check an attachtab filesystem to see if we want to remember it. */
211static int check_fs(locker_context context, locker_attachent *at, void *arg)
212{
213  /* Check in list. */
214  if (!okname(at->mountpoint, fsnames))
215    return 0;
216
217  /* Check type. */
218  if (strcmp(at->fs->name, "AFS") != 0)
219    return 0;
220
221  /* If listing all, or this was explicitly specified, then it's ok. */
222  if (!arg || fsnames)
223    return 1;
224
225  /* Else check owners. */
226  if (!locker_check_owner(context, at, arg))
227    return 0;
228
229  /* Check access */
230  return access(at->mountpoint, W_OK) == 0;
231}
232
233static int add_fs(locker_context context, locker_attachent *at, void *arg)
234{
235  struct quota_fs **fslistp = arg;
236
237  if (numfs == fssize)
238    {
239      fssize = 2 * (fssize + 1);
240      *fslistp = realloc(*fslistp, fssize * sizeof(struct quota_fs));
241      if (!*fslistp)
242        {
243          fprintf(stderr, "quota: Out of memory.\n");
244          exit(1);
245        }
246    }
247  memset(&(*fslistp)[numfs], 0, sizeof(struct quota_fs));
248  (*fslistp)[numfs].device = strdup(at->hostdir);
249  (*fslistp)[numfs].mount = strdup(at->mountpoint);
250  (*fslistp)[numfs++].type = strdup(at->fs->name);
251
252  return 0;
253}
254
255/* Check if a filesystem mountpoint is in the list to check. */
256static int okname(char *name, char **list)
257{
258  int i;
259
260  if (!list)
261    return 1;
262
263  for (i = 0; list[i]; i++)
264    {
265      if (!strcmp(name, list[i]))
266        return 1;
267    }
268  return 0;
269}
270
271#ifdef SOLARIS
272/* Solaris has a mostly compatible getmntent that just handles its
273 * arguments and names its structure elements differently.
274 */
275static struct mntent *solaris_compat_getmntent(FILE *mtab)
276{
277  struct mnttab mnt_sol;
278  static struct mntent mnt_compat;
279 
280  if (getmntent(mtab, &mnt_sol) == 0)
281    {
282      mnt_compat.mnt_fsname = mnt_sol.mnt_special;
283      mnt_compat.mnt_dir = mnt_sol.mnt_mountp;
284      mnt_compat.mnt_type = mnt_sol.mnt_fstype;
285      return &mnt_compat;
286    }
287  else
288    return NULL;
289}
290#endif
Note: See TracBrowser for help on using the repository browser.