]> andersk Git - moira.git/blame_incremental - gen/setquota.c
Command line printer manipulation client, and build goo.
[moira.git] / gen / setquota.c
... / ...
CommitLineData
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 */
14
15#ifndef lint
16static char *rcsid_setquota_c = "$Header$";
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}
This page took 1.035297 seconds and 5 git commands to generate.