source: trunk/third/moira/gen/setquota.c @ 24319

Revision 24319, 3.8 KB checked in by broder, 14 years ago (diff)
New Moira snapshot from SVN.
Line 
1/*      $Id: setquota.c 3956 2010-01-05 20:56:56Z zacheiss $
2 *
3 *      Copyright (C) 1987 by the Massachusetts Institute of Technology
4 *
5 *      Set quota on specified device for specified user to specified value.
6 *
7 *      Uses the NFS style quota system/quotactl rather than the Melbourne
8 * quota system.
9 *
10 */
11
12#ifndef lint
13static char *rcsid_setquota_c = "$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/gen/setquota.c $ $Id: setquota.c 3956 2010-01-05 20:56:56Z zacheiss $";
14#endif lint
15
16#include <stdio.h>
17#include <ctype.h>
18#include <mntent.h>
19
20#include <sys/file.h>
21#include <sys/param.h>
22#include <sys/time.h>
23#include <ufs/quota.h>
24
25#define kb(n)   (howmany(dbtob(n), 1024))
26
27static char device[20];
28static char quotafilename[30];
29static struct dqblk zblk = {0};
30
31int main(int argc, char **argv)
32{
33  int uid, uid_low, uid_high, soft_quota, qfd;
34  struct dqblk db, odb;
35  int uflag = 0;
36  int range_mode = 0;
37
38  while (argc > 4 && *argv[1] == '-')
39    {
40      switch (argv[1][1])
41        {
42        case 'u':
43          uflag = 1;
44          --argc;
45          ++argv;
46          break;
47        case 'r':
48          range_mode = 1;
49          --argc;
50          ++argv;
51          break;
52        default:
53          goto usage;
54        }
55    }
56
57  if ((argc != 4 && !range_mode) || (argc != 5 && range_mode))
58    {
59    usage:
60      fprintf(stderr, "usage: setquota [-u] special uid quota\n"
61              "setquota -r [-u] special uid_low uid_high quota\n"
62              "-u means set limit to <quota> + cur usage\n"
63              "special is a mounted filesystem special device\n"
64              "quota is in 1KB units\n");
65      exit(1);
66    }
67
68  if ((!range_mode && (!isdigit(*argv[2]) || !isdigit(*argv[3]))) ||
69      (range_mode && (!isdigit(*argv[2]) || !isdigit(*argv[3]) ||
70                      !isdigit(*argv[4]))))
71    {
72      fprintf(stderr, "setquota: uid and quota must be numeric\n");
73      goto usage;
74    }
75
76  if (range_mode)
77    {
78      uid_low = atoi(argv[2]);
79      uid_high = atoi(argv[3]);
80      soft_quota = atoi(argv[4]);
81      if (uid_low > uid_high)
82        {
83          fprintf(stderr, "setquota: range error\n");
84          exit(1);
85        }
86    }
87  else
88    {
89      uid_low = uid_high = atoi(argv[2]);
90      soft_quota = atoi(argv[3]);
91    }
92
93  get_device(argv[1]);
94
95  for (uid = uid_low; uid <= uid_high; uid++)
96    {
97      if (quotactl(Q_GETQUOTA, device, uid, &odb))
98        {
99          if (!(qfd = open(quotafilename, O_RDWR)))
100            {
101              perror("No quota file");
102              exit(1);
103            }
104
105          lseek(qfd, 32767 * sizeof(struct dqblk), L_SET);
106          write(qfd, &zblk, sizeof(struct dqblk));
107          close(qfd);
108
109          if (quotactl(Q_GETQUOTA, device, uid, &odb) != 0)
110            {
111              perror("Can't get current quota info");
112              exit(1);
113            }
114        }
115
116      db.dqb_bsoftlimit = soft_quota;
117      db.dqb_bhardlimit = (db.dqb_bsoftlimit * 6) / 5;
118      db.dqb_fsoftlimit = soft_quota / 2;
119      db.dqb_fhardlimit = (db.dqb_fsoftlimit * 6) / 5;
120      db.dqb_btimelimit = odb.dqb_btimelimit;
121      db.dqb_ftimelimit = odb.dqb_ftimelimit;
122
123      db.dqb_bsoftlimit *= btodb(1024);
124      db.dqb_bhardlimit *= btodb(1024);
125
126      if (uflag)
127        {
128          db.dqb_bhardlimit += odb.dqb_curblocks;
129          db.dqb_bsoftlimit += odb.dqb_curblocks;
130          db.dqb_fhardlimit += odb.dqb_curfiles;
131          db.dqb_fsoftlimit += odb.dqb_curfiles;
132        }
133
134      if (quotactl(Q_SETQLIM, device, uid, &db) < 0)
135        {
136          fprintf(stderr, "quotactl: %d on ", uid);
137          perror(device);
138          exit(1);
139        }
140    }
141
142  if (quotactl(Q_SYNC, device, 0, 0) < 0)
143    {
144      perror("can't sync disk quota");
145      exit(1);
146    }
147
148  exit(0);
149}
150
151get_device(char *device_or_dir)
152{
153  struct mntent *mntp;
154  FILE *fstab;
155
156  fstab = setmntent(MNTTAB, "r");
157  while (mntp = getmntent(fstab))
158    {
159      if (!strcmp(mntp->mnt_fsname, device_or_dir) ||
160          !strcmp(mntp->mnt_dir, device_or_dir))
161        {
162          strcpy(device, mntp->mnt_fsname);
163          sprintf(quotafilename, "%s/quotas", mntp->mnt_dir);
164          endmntent(fstab);
165          return;
166        }
167    }
168  fprintf(stderr, "%s not mounted.\n", device_or_dir);
169  exit(1);
170}
Note: See TracBrowser for help on using the repository browser.