6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
8 * Set quota on specified device for specified user to specified value.
10 * Uses the NFS style quota system/quotactl rather than the Melbourne
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.
18 * Revision 1.3 88/10/06 10:46:08 raeburn
19 * (mar) Don't expire timers on users currently over quota.
21 * Revision 1.1 87/09/04 21:32:47 wesommer
27 static char *rcsid_setquota_c = "$Header$";
35 #include <sys/param.h>
37 #include <ufs/quota.h>
39 #define kb(n) (howmany(dbtob(n), 1024))
41 static char device[20];
42 static char quotafilename[30];
43 static struct dqblk zblk = {0};
49 int uid, uid_low, uid_high, soft_quota, qfd;
54 while (argc > 4 && *argv[1] == '-') {
71 if ((argc != 4 && !range_mode) || (argc != 5 && range_mode)) {
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");
82 (!isdigit(*argv[2]) || !isdigit(*argv[3]))) ||
84 (!isdigit(*argv[2]) || !isdigit(*argv[3]) ||
85 !isdigit(*argv[4])))) {
86 fprintf(stderr, "setquota: uid and quota must be numeric\n");
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");
100 uid_low = uid_high = atoi(argv[2]);
101 soft_quota = atoi(argv[3]);
106 for(uid = uid_low; uid <= uid_high; uid++){
108 if (quotactl(Q_GETQUOTA, device, uid, &odb) != 0) {
110 if (!(qfd = open(quotafilename, O_RDWR))){
111 perror("No quota file");
115 lseek(qfd, 32767*sizeof(struct dqblk), L_SET);
116 write(qfd, &zblk, sizeof(struct dqblk));
119 if (quotactl(Q_GETQUOTA, device, uid, &odb) != 0) {
120 perror("Can't get current quota info");
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;
132 db.dqb_bsoftlimit *= btodb(1024);
133 db.dqb_bhardlimit *= btodb(1024);
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;
142 if (quotactl(Q_SETQLIM, device, uid, &db) < 0) {
143 fprintf (stderr, "quotactl: %d on ", uid);
149 if (quotactl(Q_SYNC, device, 0, 0) < 0) {
150 perror ("can't sync disk quota");
157 get_device(char *device_or_dir)
159 register struct mntent *mntp;
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);
172 fprintf(stderr, "%s not mounted.\n", device_or_dir);