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