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
RevLine 
[12786]1/* Copyright 1999 by the Massachusetts Institute of Technology.
[3000]2 *
[12786]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.
[2988]14 */
[5951]15
[12786]16/* This is quota, which abstracts quota-checking mechanisms for
17 * various types of lockers.
18 */
19
[14022]20static const char rcsid[] = "$Id: quota.c,v 1.27 1999-11-22 16:00:16 danw Exp $";
[12786]21
[5197]22#include <ctype.h>
[2988]23#include <pwd.h>
[13773]24#include <signal.h>
[12786]25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
[5951]29
[12786]30#include <locker.h>
31#include "quota.h"
[2988]32
[12786]33char **fsnames;
34locker_context context;
[5197]35
[12786]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);
[5197]40
[12786]41int main(int argc, char **argv)
[2988]42{
[12786]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;
[13773]52  sigset_t mask;
[2988]53
[12786]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    }
[2988]60
[13773]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
[12786]68  while ((opt = getopt(argc, argv, "af:guv")) != -1)
69    {
70      switch (opt)
71        {
72        case 'a':
73          all = 1;
74          break;
[2988]75
[12786]76        case 'v':
77          verbose = 1;
78          break;
[5951]79
[12786]80        case 'g':
81          fprintf(stderr, "quota: Group quotas no longer supported.\n");
82          exit(1);
83          break;
[4169]84
[12786]85        case 'u':
86          /* Backward-compatibility option. */
87          verbose = 1;
88          break;
[2988]89
[12786]90        case 'f':
[14022]91          if (fsind >= fssize - 1)
[12786]92            {
93              fssize = 2 * (fssize + 1);
[14022]94              fsnames = realloc(fsnames, fssize * sizeof(char *));
[12786]95              if (!fsnames)
96                {
97                  fprintf(stderr, "quota: Out of memory.\n");
98                  exit(1);
[5951]99                }
[3305]100            }
[12786]101
102          if (!strchr(optarg, '/'))
[5951]103            {
[12786]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);
[5951]114            }
[12786]115          else
116            fsnames[fsind++] = optarg;
117          break;
[3305]118
[12786]119        default:
[13593]120          fprintf(stderr, "quota: %s: unknown option\n", argv[optind - 1]);
[12786]121          usage();
122          exit(1);
[5951]123        }
124    }
[3305]125
[14022]126  if (fsind)
[5951]127    {
[14022]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;
[5197]135    }
136
[12786]137  if (optind < argc)
[5951]138    {
[12786]139      if (optind < argc - 1)
[5951]140        {
[12786]141          fprintf(stderr, "quota: Can only specify a single user.\n");
142          exit(1);
[5951]143        }
144
[12786]145      if (alldigits(argv[optind]))
[5951]146        {
[12786]147          uid = atoi(argv[optind]);
[3305]148
[12786]149          pw = getpwuid(uid);
150          if (pw)
151            user = strdup(pw->pw_name);
152          else
153            user = "(no account)";
[5951]154        }
[12786]155      else
156        {
157          user = argv[optind];
[5951]158
[12786]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);
[5197]166            }
167        }
[5951]168
[12786]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);
[5951]175        }
[3305]176    }
[12786]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);
[3305]187        }
[12786]188      user = strdup(pw->pw_name);
[5951]189    }
[3305]190
[12786]191  if (uid == 0)
192    {
193      if (verbose)
194        printf("no disk quota for %s (uid 0)\n", user);
195      exit(0);
196    }
[3305]197
[12786]198  fslist = get_fslist(all ? 0 : uid);
[3305]199
[12786]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);
[3305]209
[12786]210      if (!status && fslist[i].have_quota && verbose)
211        {
212          if (!heading_printed)
213            {
214              heading(uid, user);
215              heading_printed = 1;
[5951]216            }
[12786]217          print_quota(&fslist[i]);
[5951]218        }
[3305]219    }
[12786]220  printf("\n");
[2988]221
[12786]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]);
[5951]230        }
[2988]231    }
232
[12786]233  exit(0);
[2988]234}
235
[12786]236static void heading(uid_t uid, char *name)
[2988]237{
[12786]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");
[2988]243}
244
[12786]245static void print_quota(struct quota_fs *fs)
[2988]246{
[12786]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;
[2988]252
[12786]253  if (strlen(fs->mount) > 16)
254    printf("%s\n%-16s ", fs->mount, "");
255  else
256    printf("%-16s ", fs->mount);
[2988]257
[12786]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 ? "<<" : "");
[5951]265    }
[12786]266  else
267    printf("%30s", "");
[2988]268
[12786]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 ? "<<" : "");
[5951]276    }
[3007]277
[12786]278  printf("\n");
[2988]279}
280
[12786]281static int alldigits(char *s)
[2988]282{
[12786]283  int c;
[2988]284
[12786]285  c = *s++;
286  do {
287    if (!isdigit(c))
288      return 0;
289  } while ((c = *s++));
290  return 1;
[2988]291}
292
[12786]293static void usage(void)
[6831]294{
[12786]295  fprintf(stderr, "Usage: quota [-v] [-f filesystem...] [-u] [user]\n");
296  exit(1);
[6831]297}
Note: See TracBrowser for help on using the repository browser.