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

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