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

Revision 24068, 6.3 KB checked in by broder, 15 years ago (diff)
cd
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"))
[24068]206        {
207#ifdef ENABLE_NFS
208          status = get_nfs_quota(&fslist[i], uid, verbose);
209#else
210          status = 1;
211#endif
212        }
[12786]213      else
214        status = get_local_quota(&fslist[i], uid, verbose);
[3305]215
[12786]216      if (!status && fslist[i].have_quota && verbose)
217        {
218          if (!heading_printed)
219            {
220              heading(uid, user);
221              heading_printed = 1;
[5951]222            }
[12786]223          print_quota(&fslist[i]);
[5951]224        }
[3305]225    }
[12786]226  printf("\n");
[2988]227
[12786]228  for (i = 0; fslist[i].type; i++)
229    {
230      if (fslist[i].warn_blocks || fslist[i].warn_files)
231        {
232          if (!strcasecmp(fslist[i].type, "afs"))
233            print_afs_warning(&fslist[i]);
234          else
235            print_mounted_warning(&fslist[i]);
[5951]236        }
[2988]237    }
238
[12786]239  exit(0);
[2988]240}
241
[12786]242static void heading(uid_t uid, char *name)
[2988]243{
[12786]244  printf("Disk quotas for %s (uid %lu):\n", name, (unsigned long) uid);
245  printf("%-16s %8s %8s %8s    %8s %8s %8s\n",
246         "Filesystem",
247         "usage", "quota", "limit",
248         "files", "quota", "limit");
[2988]249}
250
[12786]251static void print_quota(struct quota_fs *fs)
[2988]252{
[12786]253  /* Ignore all-zero quotas */
254  if (!fs->dqb.dqb_bsoftlimit && !fs->dqb.dqb_bhardlimit
255      && !fs->dqb.dqb_curblocks && !fs->dqb.dqb_fsoftlimit
256      && !fs->dqb.dqb_fhardlimit && !fs->dqb.dqb_curfiles)
257    return;
[2988]258
[12786]259  if (strlen(fs->mount) > 16)
260    printf("%s\n%-16s ", fs->mount, "");
261  else
262    printf("%-16s ", fs->mount);
[2988]263
[12786]264  if (fs->have_blocks)
265    {
266      printf("%8u %8u %8u %2s ",
267             fs->dqb.dqb_curblocks / 2,
268             fs->dqb.dqb_bsoftlimit / 2,
269             fs->dqb.dqb_bhardlimit / 2,
270             fs->warn_blocks ? "<<" : "");
[5951]271    }
[12786]272  else
273    printf("%30s", "");
[2988]274
[12786]275  if (fs->have_files)
276    {
277      printf("%8u %8u %8u %2s ",
278             fs->dqb.dqb_curfiles,
279             fs->dqb.dqb_fsoftlimit,
280             fs->dqb.dqb_fhardlimit,
281             fs->warn_files ? "<<" : "");
[5951]282    }
[3007]283
[12786]284  printf("\n");
[2988]285}
286
[12786]287static int alldigits(char *s)
[2988]288{
[12786]289  int c;
[2988]290
[12786]291  c = *s++;
292  do {
293    if (!isdigit(c))
294      return 0;
295  } while ((c = *s++));
296  return 1;
[2988]297}
298
[12786]299static void usage(void)
[6831]300{
[12786]301  fprintf(stderr, "Usage: quota [-v] [-f filesystem...] [-u] [user]\n");
302  exit(1);
[6831]303}
Note: See TracBrowser for help on using the repository browser.