source: trunk/athena/bin/quota/quota.c @ 14022

Revision 14022, 6.2 KB checked in by danw, 25 years ago (diff)
make -f work correctly
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/* This is quota, which abstracts quota-checking mechanisms for
17 * various types of lockers.
18 */
19
20static const char rcsid[] = "$Id: quota.c,v 1.27 1999-11-22 16:00:16 danw Exp $";
21
22#include <ctype.h>
23#include <pwd.h>
24#include <signal.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
29
30#include <locker.h>
31#include "quota.h"
32
33char **fsnames;
34locker_context context;
35
36static void usage(void);
37static void print_quota(struct quota_fs *fs);
38static void heading(uid_t uid, char *name);
39static int alldigits(char *s);
40
41int main(int argc, char **argv)
42{
43  int opt, i, status;
44  struct passwd *pw;
45  uid_t myuid;
46  int all = 0;
47  char *user;
48  uid_t uid;
49  int fsind = 0, fssize = 0, heading_printed = 0;
50  int verbose = 0;
51  struct quota_fs *fslist = NULL;
52  sigset_t mask;
53
54  myuid = getuid();
55  if (locker_init(&context, myuid, NULL, NULL) != LOCKER_SUCCESS)
56    {
57      fprintf(stderr, "quota: Could not initialize locker library.\n");
58      exit(1);
59    }
60
61  /* Block ^Z to prevent holding locks on the attachtab. */
62  sigemptyset(&mask);
63  sigaddset(&mask, SIGTSTP);
64  sigaddset(&mask, SIGTTOU);
65  sigaddset(&mask, SIGTTIN);
66  sigprocmask(SIG_BLOCK, &mask, NULL);
67
68  while ((opt = getopt(argc, argv, "af:guv")) != -1)
69    {
70      switch (opt)
71        {
72        case 'a':
73          all = 1;
74          break;
75
76        case 'v':
77          verbose = 1;
78          break;
79
80        case 'g':
81          fprintf(stderr, "quota: Group quotas no longer supported.\n");
82          exit(1);
83          break;
84
85        case 'u':
86          /* Backward-compatibility option. */
87          verbose = 1;
88          break;
89
90        case 'f':
91          if (fsind >= fssize - 1)
92            {
93              fssize = 2 * (fssize + 1);
94              fsnames = realloc(fsnames, fssize * sizeof(char *));
95              if (!fsnames)
96                {
97                  fprintf(stderr, "quota: Out of memory.\n");
98                  exit(1);
99                }
100            }
101
102          if (!strchr(optarg, '/'))
103            {
104              locker_attachent *at;
105
106              if (locker_read_attachent(context, optarg, &at) !=
107                  LOCKER_SUCCESS)
108                {
109                  fprintf(stderr, "quota: Unknown filesystem %s.\n", optarg);
110                  exit(1);
111                }
112              fsnames[fsind++] = strdup(at->mountpoint);
113              locker_free_attachent(context, at);
114            }
115          else
116            fsnames[fsind++] = optarg;
117          break;
118
119        default:
120          fprintf(stderr, "quota: %s: unknown option\n", argv[optind - 1]);
121          usage();
122          exit(1);
123        }
124    }
125
126  if (fsind)
127    {
128      if (all)
129        {
130          fprintf(stderr, "quota: Can't use both -a and -f\n");
131          usage();
132          exit(1);
133        }
134      fsnames[fsind] = NULL;
135    }
136
137  if (optind < argc)
138    {
139      if (optind < argc - 1)
140        {
141          fprintf(stderr, "quota: Can only specify a single user.\n");
142          exit(1);
143        }
144
145      if (alldigits(argv[optind]))
146        {
147          uid = atoi(argv[optind]);
148
149          pw = getpwuid(uid);
150          if (pw)
151            user = strdup(pw->pw_name);
152          else
153            user = "(no account)";
154        }
155      else
156        {
157          user = argv[optind];
158
159          pw = getpwnam(user);
160          if (pw)
161            uid = pw->pw_uid;
162          else
163            {
164              fprintf(stderr, "quota: No passwd entry for user %s.\n", user);
165              exit(1);
166            }
167        }
168
169      /* Check permission if not root. */
170      if (myuid != 0 && uid != myuid)
171        {
172          fprintf(stderr, "quota: %s (uid %lu): permission denied\n",
173                  user, (unsigned long) uid);
174          exit(1);
175        }
176    }
177  else
178    {
179      /* Use real uid. */
180      uid = myuid;
181      pw = getpwuid(myuid);
182      if (!pw)
183        {
184          fprintf(stderr, "quota: Could not get password entry for uid %lu.\n",
185                  (unsigned long) myuid);
186          exit(1);
187        }
188      user = strdup(pw->pw_name);
189    }
190
191  if (uid == 0)
192    {
193      if (verbose)
194        printf("no disk quota for %s (uid 0)\n", user);
195      exit(0);
196    }
197
198  fslist = get_fslist(all ? 0 : uid);
199
200  /* Now print quotas */
201  for (i = 0; fslist[i].type; i++)
202    {
203      if (!strcasecmp(fslist[i].type, "afs"))
204        status = get_afs_quota(&fslist[i], uid, verbose);
205      else if (!strcasecmp(fslist[i].type, "nfs"))
206        status = get_nfs_quota(&fslist[i], uid, verbose);
207      else
208        status = get_local_quota(&fslist[i], uid, verbose);
209
210      if (!status && fslist[i].have_quota && verbose)
211        {
212          if (!heading_printed)
213            {
214              heading(uid, user);
215              heading_printed = 1;
216            }
217          print_quota(&fslist[i]);
218        }
219    }
220  printf("\n");
221
222  for (i = 0; fslist[i].type; i++)
223    {
224      if (fslist[i].warn_blocks || fslist[i].warn_files)
225        {
226          if (!strcasecmp(fslist[i].type, "afs"))
227            print_afs_warning(&fslist[i]);
228          else
229            print_mounted_warning(&fslist[i]);
230        }
231    }
232
233  exit(0);
234}
235
236static void heading(uid_t uid, char *name)
237{
238  printf("Disk quotas for %s (uid %lu):\n", name, (unsigned long) uid);
239  printf("%-16s %8s %8s %8s    %8s %8s %8s\n",
240         "Filesystem",
241         "usage", "quota", "limit",
242         "files", "quota", "limit");
243}
244
245static void print_quota(struct quota_fs *fs)
246{
247  /* Ignore all-zero quotas */
248  if (!fs->dqb.dqb_bsoftlimit && !fs->dqb.dqb_bhardlimit
249      && !fs->dqb.dqb_curblocks && !fs->dqb.dqb_fsoftlimit
250      && !fs->dqb.dqb_fhardlimit && !fs->dqb.dqb_curfiles)
251    return;
252
253  if (strlen(fs->mount) > 16)
254    printf("%s\n%-16s ", fs->mount, "");
255  else
256    printf("%-16s ", fs->mount);
257
258  if (fs->have_blocks)
259    {
260      printf("%8u %8u %8u %2s ",
261             fs->dqb.dqb_curblocks / 2,
262             fs->dqb.dqb_bsoftlimit / 2,
263             fs->dqb.dqb_bhardlimit / 2,
264             fs->warn_blocks ? "<<" : "");
265    }
266  else
267    printf("%30s", "");
268
269  if (fs->have_files)
270    {
271      printf("%8u %8u %8u %2s ",
272             fs->dqb.dqb_curfiles,
273             fs->dqb.dqb_fsoftlimit,
274             fs->dqb.dqb_fhardlimit,
275             fs->warn_files ? "<<" : "");
276    }
277
278  printf("\n");
279}
280
281static int alldigits(char *s)
282{
283  int c;
284
285  c = *s++;
286  do {
287    if (!isdigit(c))
288      return 0;
289  } while ((c = *s++));
290  return 1;
291}
292
293static void usage(void)
294{
295  fprintf(stderr, "Usage: quota [-v] [-f filesystem...] [-u] [user]\n");
296  exit(1);
297}
Note: See TracBrowser for help on using the repository browser.