]> andersk Git - moira.git/blob - gen/setquota.c
fix proc delcaration to pass cc
[moira.git] / gen / setquota.c
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Header$
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  *      $Log$
14  *      Revision 1.6  1990-03-07 17:41:22  mar
15  *      fix proc delcaration to pass cc
16  *
17  * Revision 1.5  90/03/06  15:59:08  jnrees
18  * x*.5 replaced with x/2;
19  * x*1.2 with (x*6)/5;
20  * This avoids linking in the floating-point library.
21  * 
22  * Revision 1.4  90/01/27  19:48:05  jnrees
23  * Grows quotas file if necessary
24  * Allows setting quota for a range of uid's.
25  * 
26  * Revision 1.3  88/10/06  10:46:08  raeburn
27  * (mar) Don't expire timers on users currently over quota.
28  *
29  * Revision 1.1  87/09/04  21:32:47  wesommer
30  * Initial revision
31  *
32  */
33
34 #ifndef lint
35 static char *rcsid_setquota_c = "$Header$";
36 #endif lint
37
38 #include <stdio.h>
39 #include <ctype.h>
40 #include <mntent.h>
41
42 #include <sys/file.h>
43 #include <sys/param.h>
44 #include <sys/time.h>
45 #include <ufs/quota.h>
46
47 #define kb(n)   (howmany(dbtob(n), 1024))
48
49 static char device[20];
50 static char quotafilename[30];
51 static struct dqblk zblk = {0};
52
53 main(argc, argv)
54         int argc;
55         char **argv;
56 {
57         int uid, uid_low, uid_high, soft_quota, qfd;
58         struct dqblk db, odb;
59         int uflag = 0;
60         int range_mode = 0;
61         
62         while (argc > 4 && *argv[1] == '-') {
63           switch(argv[1][1]) {
64           case 'u':
65             uflag = 1;
66             --argc;
67             ++argv;
68             break;
69           case 'r':
70             range_mode = 1;
71             --argc;
72             ++argv;
73             break;
74           default:
75             goto usage;
76           }
77         }
78         
79         if ((argc != 4 && !range_mode) || (argc != 5 && range_mode)) {
80         usage:
81                 fprintf(stderr, "usage: setquota [-u] special uid quota\n\
82        setquota -r [-u] special uid_low uid_high quota\n\
83 -u means set limit to <quota> + cur usage\n\
84 special is a mounted filesystem special device\n\
85 quota is in 1KB units\n");
86                 exit(1);
87         }
88
89         if ((!range_mode &&
90              (!isdigit(*argv[2]) || !isdigit(*argv[3]))) ||
91             (range_mode &&
92              (!isdigit(*argv[2]) || !isdigit(*argv[3]) ||
93               !isdigit(*argv[4])))) {
94           fprintf(stderr, "setquota: uid and quota must be numeric\n");
95           goto usage;
96         }
97
98         if (range_mode){
99           uid_low = atoi(argv[2]);
100           uid_high = atoi(argv[3]);
101           soft_quota = atoi(argv[4]);
102           if (uid_low > uid_high){
103             fprintf(stderr, "setquota: range error\n");
104             exit(1);
105           }
106         }
107         else{
108           uid_low = uid_high = atoi(argv[2]);
109           soft_quota = atoi(argv[3]);
110         }
111         
112         get_device(argv[1]);
113
114         for(uid = uid_low; uid <= uid_high; uid++){
115
116           if (quotactl(Q_GETQUOTA, device, uid, &odb) != 0) {
117
118             if (!(qfd = open(quotafilename, O_RDWR))){
119               perror("No quota file");
120               exit(1);
121             }
122
123             lseek(qfd, 32767*sizeof(struct dqblk), L_SET);
124             write(qfd, &zblk, sizeof(struct dqblk));
125             close(qfd);
126
127             if (quotactl(Q_GETQUOTA, device, uid, &odb) != 0) {
128               perror("Can't get current quota info");
129               exit(1);
130             }
131           }
132
133           db.dqb_bsoftlimit = soft_quota;
134           db.dqb_bhardlimit = (db.dqb_bsoftlimit * 6) / 5;
135           db.dqb_fsoftlimit = soft_quota / 2;
136           db.dqb_fhardlimit = (db.dqb_fsoftlimit * 6) / 5;
137           db.dqb_btimelimit = odb.dqb_btimelimit;
138           db.dqb_ftimelimit = odb.dqb_ftimelimit;
139
140           db.dqb_bsoftlimit *= btodb(1024);
141           db.dqb_bhardlimit *= btodb(1024);
142
143           if (uflag) {
144             db.dqb_bhardlimit += odb.dqb_curblocks;
145             db.dqb_bsoftlimit += odb.dqb_curblocks;
146             db.dqb_fhardlimit += odb.dqb_curfiles;
147             db.dqb_fsoftlimit += odb.dqb_curfiles;
148           }
149         
150           if (quotactl(Q_SETQLIM, device, uid, &db) < 0) {
151             fprintf (stderr, "quotactl: %d on ", uid);
152             perror (device);
153             exit (1);
154           }
155         }
156         
157         if (quotactl(Q_SYNC, device, 0, 0) < 0) {
158           perror ("can't sync disk quota");
159           exit (1);
160         }
161
162         exit (0);
163 }
164         
165 get_device(device_or_dir)
166 char *device_or_dir;
167 {
168   register struct mntent *mntp;
169   FILE *fstab;
170
171   fstab = setmntent(MNTTAB, "r");
172   while(mntp = getmntent(fstab)){
173     if ((strcmp(mntp->mnt_fsname, device_or_dir) == 0) ||
174         (strcmp(mntp->mnt_dir, device_or_dir) == 0)){
175       strcpy(device, mntp->mnt_fsname);
176       sprintf(quotafilename, "%s/quotas", mntp->mnt_dir);
177       endmntent(fstab);
178       return;
179     }
180   }
181   fprintf(stderr, "%s not mounted.\n", device_or_dir);
182   exit(1);
183 }
This page took 0.211622 seconds and 5 git commands to generate.