edquota.c (180187) | edquota.c (207736) |
---|---|
1/* 2 * Copyright (c) 1980, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Robert Elz at The University of Melbourne. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 29 unchanged lines hidden (view full) --- 38#endif /* not lint */ 39 40#ifndef lint 41static char sccsid[] = "@(#)edquota.c 8.1 (Berkeley) 6/6/93"; 42#endif /* not lint */ 43#endif 44 45#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 1980, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Robert Elz at The University of Melbourne. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 29 unchanged lines hidden (view full) --- 38#endif /* not lint */ 39 40#ifndef lint 41static char sccsid[] = "@(#)edquota.c 8.1 (Berkeley) 6/6/93"; 42#endif /* not lint */ 43#endif 44 45#include <sys/cdefs.h> |
46__FBSDID("$FreeBSD: head/usr.sbin/edquota/edquota.c 180187 2008-07-02 15:51:59Z des $"); | 46__FBSDID("$FreeBSD: head/usr.sbin/edquota/edquota.c 207736 2010-05-07 00:41:12Z mckusick $"); |
47 48/* 49 * Disk quota editor. 50 */ 51 52#include <sys/param.h> 53#include <sys/stat.h> 54#include <sys/file.h> 55#include <sys/mount.h> 56#include <sys/wait.h> 57#include <ufs/ufs/quota.h> | 47 48/* 49 * Disk quota editor. 50 */ 51 52#include <sys/param.h> 53#include <sys/stat.h> 54#include <sys/file.h> 55#include <sys/mount.h> 56#include <sys/wait.h> 57#include <ufs/ufs/quota.h> |
58 |
|
58#include <ctype.h> 59#include <err.h> 60#include <errno.h> 61#include <fstab.h> 62#include <grp.h> | 59#include <ctype.h> 60#include <err.h> 61#include <errno.h> 62#include <fstab.h> 63#include <grp.h> |
64#include <inttypes.h> 65#include <libutil.h> |
|
63#include <pwd.h> 64#include <signal.h> 65#include <stdio.h> 66#include <stdlib.h> 67#include <string.h> 68#include <unistd.h> | 66#include <pwd.h> 67#include <signal.h> 68#include <stdio.h> 69#include <stdlib.h> 70#include <string.h> 71#include <unistd.h> |
72 |
|
69#include "pathnames.h" 70 | 73#include "pathnames.h" 74 |
71const char *qfname = QUOTAFILENAME; | 75/* Let's be paranoid about block size */ 76#if 10 > DEV_BSHIFT 77#define dbtokb(db) \ 78 ((off_t)(db) >> (10-DEV_BSHIFT)) 79#elif 10 < DEV_BSHIFT 80#define dbtokb(db) \ 81 ((off_t)(db) << (DEV_BSHIFT-10)) 82#else 83#define dbtokb(db) (db) 84#endif 85 |
72const char *qfextension[] = INITQFNAMES; | 86const char *qfextension[] = INITQFNAMES; |
73const char *quotagroup = QUOTAGROUP; | |
74char tmpfil[] = _PATH_TMP; | 87char tmpfil[] = _PATH_TMP; |
88int hflag; |
|
75 76struct quotause { 77 struct quotause *next; | 89 90struct quotause { 91 struct quotause *next; |
78 long flags; | 92 struct quotafile *qf; |
79 struct dqblk dqblk; | 93 struct dqblk dqblk; |
94 int flags; |
|
80 char fsname[MAXPATHLEN + 1]; | 95 char fsname[MAXPATHLEN + 1]; |
81 char qfname[1]; /* actually longer */ | |
82}; 83#define FOUND 0x01 84 85int alldigits(const char *s); | 96}; 97#define FOUND 0x01 98 99int alldigits(const char *s); |
86int cvtatos(time_t, char *, time_t *); 87char *cvtstoa(time_t); | 100int cvtatos(uint64_t, char *, uint64_t *); 101char *cvtstoa(uint64_t); 102uint64_t cvtblkval(uint64_t, char, const char *); 103uint64_t cvtinoval(uint64_t, char, const char *); |
88int editit(char *); | 104int editit(char *); |
105char *fmthumanvalblks(int64_t); 106char *fmthumanvalinos(int64_t); |
|
89void freeprivs(struct quotause *); 90int getentry(const char *, int); 91struct quotause *getprivs(long, int, char *); | 107void freeprivs(struct quotause *); 108int getentry(const char *, int); 109struct quotause *getprivs(long, int, char *); |
92int hasquota(struct fstab *, int, char **); 93void putprivs(long, int, struct quotause *); | 110void putprivs(long, struct quotause *); |
94int readprivs(struct quotause *, char *); 95int readtimes(struct quotause *, char *); 96static void usage(void); 97int writetimes(struct quotause *, int, int); 98int writeprivs(struct quotause *, int, char *, int); 99 100int 101main(int argc, char *argv[]) 102{ 103 struct quotause *qup, *protoprivs, *curprivs; 104 long id, protoid; | 111int readprivs(struct quotause *, char *); 112int readtimes(struct quotause *, char *); 113static void usage(void); 114int writetimes(struct quotause *, int, int); 115int writeprivs(struct quotause *, int, char *, int); 116 117int 118main(int argc, char *argv[]) 119{ 120 struct quotause *qup, *protoprivs, *curprivs; 121 long id, protoid; |
105 long long lim; | |
106 int i, quotatype, range, tmpfd; 107 uid_t startuid, enduid; | 122 int i, quotatype, range, tmpfd; 123 uid_t startuid, enduid; |
108 u_int32_t *limp; 109 char *protoname, *cp, *oldoptarg; | 124 uint64_t lim; 125 char *protoname, *cp, *endpt, *oldoptarg; |
110 int eflag = 0, tflag = 0, pflag = 0, ch; 111 char *fspath = NULL; 112 char buf[MAXLOGNAME]; 113 114 if (argc < 2) 115 usage(); 116 if (getuid()) 117 errx(1, "permission denied"); 118 quotatype = USRQUOTA; 119 protoprivs = NULL; 120 curprivs = NULL; 121 protoname = NULL; | 126 int eflag = 0, tflag = 0, pflag = 0, ch; 127 char *fspath = NULL; 128 char buf[MAXLOGNAME]; 129 130 if (argc < 2) 131 usage(); 132 if (getuid()) 133 errx(1, "permission denied"); 134 quotatype = USRQUOTA; 135 protoprivs = NULL; 136 curprivs = NULL; 137 protoname = NULL; |
122 while ((ch = getopt(argc, argv, "ugtf:p:e:")) != -1) { | 138 while ((ch = getopt(argc, argv, "ughtf:p:e:")) != -1) { |
123 switch(ch) { 124 case 'f': 125 fspath = optarg; 126 break; 127 case 'p': | 139 switch(ch) { 140 case 'f': 141 fspath = optarg; 142 break; 143 case 'p': |
144 if (eflag) { 145 warnx("cannot specify both -e and -p"); 146 usage(); 147 /* not reached */ 148 } |
|
128 protoname = optarg; 129 pflag++; 130 break; 131 case 'g': 132 quotatype = GRPQUOTA; 133 break; | 149 protoname = optarg; 150 pflag++; 151 break; 152 case 'g': 153 quotatype = GRPQUOTA; 154 break; |
155 case 'h': 156 hflag++; 157 break; |
|
134 case 'u': 135 quotatype = USRQUOTA; 136 break; 137 case 't': 138 tflag++; 139 break; 140 case 'e': | 158 case 'u': 159 quotatype = USRQUOTA; 160 break; 161 case 't': 162 tflag++; 163 break; 164 case 'e': |
141 if ((qup = malloc(sizeof(*qup))) == NULL) | 165 if (pflag) { 166 warnx("cannot specify both -e and -p"); 167 usage(); 168 /* not reached */ 169 } 170 if ((qup = calloc(1, sizeof(*qup))) == NULL) |
142 errx(2, "out of memory"); | 171 errx(2, "out of memory"); |
143 bzero(qup, sizeof(*qup)); 144 i = 0; | |
145 oldoptarg = optarg; | 172 oldoptarg = optarg; |
146 for (cp = optarg; (cp = strsep(&optarg, ":")) != NULL; 147 i++) { | 173 for (i = 0, cp = optarg; 174 (cp = strsep(&optarg, ":")) != NULL; i++) { |
148 if (cp != oldoptarg) 149 *(cp - 1) = ':'; | 175 if (cp != oldoptarg) 176 *(cp - 1) = ':'; |
150 limp = NULL; | 177 if (i > 0 && !isdigit(*cp)) { 178 warnx("incorrect quota specification: " 179 "%s", oldoptarg); 180 usage(); 181 /* Not Reached */ 182 } |
151 switch (i) { 152 case 0: 153 strlcpy(qup->fsname, cp, 154 sizeof(qup->fsname)); 155 break; 156 case 1: | 183 switch (i) { 184 case 0: 185 strlcpy(qup->fsname, cp, 186 sizeof(qup->fsname)); 187 break; 188 case 1: |
157 limp = &qup->dqblk.dqb_bsoftlimit; 158 break; | 189 lim = strtoll(cp, &endpt, 10); 190 qup->dqblk.dqb_bsoftlimit = 191 cvtblkval(lim, *endpt, 192 "block soft limit"); 193 continue; |
159 case 2: | 194 case 2: |
160 limp = &qup->dqblk.dqb_bhardlimit; 161 break; | 195 lim = strtoll(cp, &endpt, 10); 196 qup->dqblk.dqb_bhardlimit = 197 cvtblkval(lim, *endpt, 198 "block hard limit"); 199 continue; |
162 case 3: | 200 case 3: |
163 limp = &qup->dqblk.dqb_isoftlimit; 164 break; | 201 lim = strtoll(cp, &endpt, 10); 202 qup->dqblk.dqb_isoftlimit = 203 cvtinoval(lim, *endpt, 204 "inode soft limit"); 205 continue; |
165 case 4: | 206 case 4: |
166 limp = &qup->dqblk.dqb_ihardlimit; 167 break; | 207 lim = strtoll(cp, &endpt, 10); 208 qup->dqblk.dqb_ihardlimit = 209 cvtinoval(lim, *endpt, 210 "inode hard limit"); 211 continue; |
168 default: 169 warnx("incorrect quota specification: " 170 "%s", oldoptarg); 171 usage(); | 212 default: 213 warnx("incorrect quota specification: " 214 "%s", oldoptarg); 215 usage(); |
172 break; /* XXX: report an error */ | 216 /* Not Reached */ |
173 } | 217 } |
174 if (limp != NULL) { 175 lim = strtoll(cp, NULL, 10); 176 if (lim < 0 || lim > UINT_MAX) 177 errx(1, "invalid limit value: " 178 "%lld", lim); 179 *limp = (u_int32_t)lim; 180 } | |
181 } | 218 } |
182 qup->dqblk.dqb_bsoftlimit = 183 btodb((off_t)qup->dqblk.dqb_bsoftlimit * 1024); 184 qup->dqblk.dqb_bhardlimit = 185 btodb((off_t)qup->dqblk.dqb_bhardlimit * 1024); | |
186 if (protoprivs == NULL) { 187 protoprivs = curprivs = qup; 188 } else { 189 curprivs->next = qup; 190 curprivs = qup; 191 } 192 eflag++; | 219 if (protoprivs == NULL) { 220 protoprivs = curprivs = qup; 221 } else { 222 curprivs->next = qup; 223 curprivs = qup; 224 } 225 eflag++; |
193 pflag++; | |
194 break; 195 default: 196 usage(); | 226 break; 227 default: 228 usage(); |
229 /* Not Reached */ |
|
197 } 198 } 199 argc -= optind; 200 argv += optind; | 230 } 231 } 232 argc -= optind; 233 argv += optind; |
201 if (pflag) { 202 if (protoprivs == NULL) { | 234 if (pflag || eflag) { 235 if (pflag) { |
203 if ((protoid = getentry(protoname, quotatype)) == -1) 204 exit(1); 205 protoprivs = getprivs(protoid, quotatype, fspath); | 236 if ((protoid = getentry(protoname, quotatype)) == -1) 237 exit(1); 238 protoprivs = getprivs(protoid, quotatype, fspath); |
239 if (protoprivs == NULL) 240 exit(0); |
|
206 for (qup = protoprivs; qup; qup = qup->next) { 207 qup->dqblk.dqb_btime = 0; 208 qup->dqblk.dqb_itime = 0; 209 } 210 } 211 for (; argc-- > 0; argv++) { 212 if (strspn(*argv, "0123456789-") == strlen(*argv) && 213 (cp = strchr(*argv, '-')) != NULL) { --- 13 unchanged lines hidden (view full) --- 227 if (range) 228 snprintf(buf, sizeof(buf), "%d", 229 startuid); 230 else 231 snprintf(buf, sizeof(buf), "%s", 232 *argv); 233 if ((id = getentry(buf, quotatype)) < 0) 234 continue; | 241 for (qup = protoprivs; qup; qup = qup->next) { 242 qup->dqblk.dqb_btime = 0; 243 qup->dqblk.dqb_itime = 0; 244 } 245 } 246 for (; argc-- > 0; argv++) { 247 if (strspn(*argv, "0123456789-") == strlen(*argv) && 248 (cp = strchr(*argv, '-')) != NULL) { --- 13 unchanged lines hidden (view full) --- 262 if (range) 263 snprintf(buf, sizeof(buf), "%d", 264 startuid); 265 else 266 snprintf(buf, sizeof(buf), "%s", 267 *argv); 268 if ((id = getentry(buf, quotatype)) < 0) 269 continue; |
235 if (eflag) { 236 for (qup = protoprivs; qup; 237 qup = qup->next) { 238 curprivs = getprivs(id, 239 quotatype, qup->fsname); 240 if (curprivs == NULL) 241 continue; 242 strcpy(qup->qfname, 243 curprivs->qfname); 244 strcpy(qup->fsname, 245 curprivs->fsname); 246 } | 270 if (pflag) { 271 putprivs(id, protoprivs); 272 continue; |
247 } | 273 } |
248 putprivs(id, quotatype, protoprivs); | 274 for (qup = protoprivs; qup; qup = qup->next) { 275 curprivs = getprivs(id, quotatype, 276 qup->fsname); 277 if (curprivs == NULL) 278 continue; 279 curprivs->dqblk = qup->dqblk; 280 putprivs(id, curprivs); 281 freeprivs(curprivs); 282 } |
249 } 250 } | 283 } 284 } |
285 if (pflag) 286 freeprivs(protoprivs); |
|
251 exit(0); 252 } 253 tmpfd = mkstemp(tmpfil); 254 fchown(tmpfd, getuid(), getgid()); 255 if (tflag) { | 287 exit(0); 288 } 289 tmpfd = mkstemp(tmpfil); 290 fchown(tmpfd, getuid(), getgid()); 291 if (tflag) { |
256 protoprivs = getprivs(0, quotatype, fspath); 257 if (writetimes(protoprivs, tmpfd, quotatype) == 0) 258 exit(1); 259 if (editit(tmpfil) && readtimes(protoprivs, tmpfil)) 260 putprivs(0L, quotatype, protoprivs); 261 freeprivs(protoprivs); | 292 if ((protoprivs = getprivs(0, quotatype, fspath)) != NULL) { 293 if (writetimes(protoprivs, tmpfd, quotatype) != 0 && 294 editit(tmpfil) && readtimes(protoprivs, tmpfil)) 295 putprivs(0L, protoprivs); 296 freeprivs(protoprivs); 297 } |
262 close(tmpfd); 263 unlink(tmpfil); 264 exit(0); 265 } 266 for ( ; argc > 0; argc--, argv++) { 267 if ((id = getentry(*argv, quotatype)) == -1) 268 continue; | 298 close(tmpfd); 299 unlink(tmpfil); 300 exit(0); 301 } 302 for ( ; argc > 0; argc--, argv++) { 303 if ((id = getentry(*argv, quotatype)) == -1) 304 continue; |
269 curprivs = getprivs(id, quotatype, fspath); | 305 if ((curprivs = getprivs(id, quotatype, fspath)) == NULL) 306 exit(1); |
270 if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0) 271 continue; 272 if (editit(tmpfil) && readprivs(curprivs, tmpfil)) | 307 if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0) 308 continue; 309 if (editit(tmpfil) && readprivs(curprivs, tmpfil)) |
273 putprivs(id, quotatype, curprivs); | 310 putprivs(id, curprivs); |
274 freeprivs(curprivs); 275 } 276 close(tmpfd); 277 unlink(tmpfil); 278 exit(0); 279} 280 281static void 282usage(void) 283{ 284 fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", | 311 freeprivs(curprivs); 312 } 313 close(tmpfd); 314 unlink(tmpfil); 315 exit(0); 316} 317 318static void 319usage(void) 320{ 321 fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", |
285 "usage: edquota [-u] [-f fspath] [-p username] username ...", | 322 "usage: edquota [-uh] [-f fspath] [-p username] username ...", |
286 " edquota [-u] -e fspath[:bslim[:bhlim[:islim[:ihlim]]]] [-e ...]", 287 " username ...", | 323 " edquota [-u] -e fspath[:bslim[:bhlim[:islim[:ihlim]]]] [-e ...]", 324 " username ...", |
288 " edquota -g [-f fspath] [-p groupname] groupname ...", | 325 " edquota -g [-h] [-f fspath] [-p groupname] groupname ...", |
289 " edquota -g -e fspath[:bslim[:bhlim[:islim[:ihlim]]]] [-e ...]", 290 " groupname ...", 291 " edquota [-u] -t [-f fspath]", 292 " edquota -g -t [-f fspath]"); 293 exit(1); 294} 295 296/* --- 9 unchanged lines hidden (view full) --- 306 307 if (alldigits(name)) 308 return (atoi(name)); 309 switch(quotatype) { 310 case USRQUOTA: 311 if ((pw = getpwnam(name))) 312 return (pw->pw_uid); 313 warnx("%s: no such user", name); | 326 " edquota -g -e fspath[:bslim[:bhlim[:islim[:ihlim]]]] [-e ...]", 327 " groupname ...", 328 " edquota [-u] -t [-f fspath]", 329 " edquota -g -t [-f fspath]"); 330 exit(1); 331} 332 333/* --- 9 unchanged lines hidden (view full) --- 343 344 if (alldigits(name)) 345 return (atoi(name)); 346 switch(quotatype) { 347 case USRQUOTA: 348 if ((pw = getpwnam(name))) 349 return (pw->pw_uid); 350 warnx("%s: no such user", name); |
351 sleep(3); |
|
314 break; 315 case GRPQUOTA: 316 if ((gr = getgrnam(name))) 317 return (gr->gr_gid); 318 warnx("%s: no such group", name); | 352 break; 353 case GRPQUOTA: 354 if ((gr = getgrnam(name))) 355 return (gr->gr_gid); 356 warnx("%s: no such group", name); |
357 sleep(3); |
|
319 break; 320 default: 321 warnx("%d: unknown quota type", quotatype); | 358 break; 359 default: 360 warnx("%d: unknown quota type", quotatype); |
361 sleep(3); |
|
322 break; 323 } 324 sleep(1); 325 return (-1); 326} 327 328/* 329 * Collect the requested quota information. 330 */ 331struct quotause * 332getprivs(long id, int quotatype, char *fspath) 333{ | 362 break; 363 } 364 sleep(1); 365 return (-1); 366} 367 368/* 369 * Collect the requested quota information. 370 */ 371struct quotause * 372getprivs(long id, int quotatype, char *fspath) 373{ |
374 struct quotafile *qf; |
|
334 struct fstab *fs; 335 struct quotause *qup, *quptail; 336 struct quotause *quphead; | 375 struct fstab *fs; 376 struct quotause *qup, *quptail; 377 struct quotause *quphead; |
337 int qcmd, qupsize, fd; 338 char *qfpathname; 339 static int warned = 0; | |
340 341 setfsent(); 342 quphead = quptail = NULL; | 378 379 setfsent(); 380 quphead = quptail = NULL; |
343 qcmd = QCMD(Q_GETQUOTA, quotatype); | |
344 while ((fs = getfsent())) { 345 if (fspath && *fspath && strcmp(fspath, fs->fs_spec) && 346 strcmp(fspath, fs->fs_file)) 347 continue; 348 if (strcmp(fs->fs_vfstype, "ufs")) 349 continue; | 381 while ((fs = getfsent())) { 382 if (fspath && *fspath && strcmp(fspath, fs->fs_spec) && 383 strcmp(fspath, fs->fs_file)) 384 continue; 385 if (strcmp(fs->fs_vfstype, "ufs")) 386 continue; |
350 if (!hasquota(fs, quotatype, &qfpathname)) | 387 if ((qf = quota_open(fs, quotatype, O_CREAT|O_RDWR)) == NULL) { 388 if (errno != EOPNOTSUPP) 389 warn("cannot open quotas on %s", fs->fs_file); |
351 continue; | 390 continue; |
352 qupsize = sizeof(*qup) + strlen(qfpathname); 353 if ((qup = (struct quotause *)malloc(qupsize)) == NULL) | 391 } 392 if ((qup = (struct quotause *)calloc(1, sizeof(*qup))) == NULL) |
354 errx(2, "out of memory"); | 393 errx(2, "out of memory"); |
355 if (quotactl(fs->fs_file, qcmd, id, &qup->dqblk) != 0) { 356 if (errno == EOPNOTSUPP && !warned) { 357 warned++; 358 warnx("warning: quotas are not compiled into this kernel"); 359 sleep(3); 360 } 361 if ((fd = open(qfpathname, O_RDONLY)) < 0) { 362 fd = open(qfpathname, O_RDWR|O_CREAT, 0640); 363 if (fd < 0 && errno != ENOENT) { 364 warn("%s", qfpathname); 365 free(qup); 366 continue; 367 } 368 warnx("creating quota file %s", qfpathname); 369 sleep(3); 370 (void) fchown(fd, getuid(), 371 getentry(quotagroup, GRPQUOTA)); 372 (void) fchmod(fd, 0640); 373 } 374 if (lseek(fd, (off_t)id * sizeof(struct dqblk), 375 L_SET) < 0) { 376 warn("seek error on %s", qfpathname); 377 close(fd); 378 free(qup); 379 continue; 380 } 381 switch (read(fd, &qup->dqblk, sizeof(struct dqblk))) { 382 case 0: /* EOF */ 383 /* 384 * Convert implicit 0 quota (EOF) 385 * into an explicit one (zero'ed dqblk) 386 */ 387 bzero((caddr_t)&qup->dqblk, 388 sizeof(struct dqblk)); 389 break; 390 391 case sizeof(struct dqblk): /* OK */ 392 break; 393 394 default: /* ERROR */ 395 warn("read error in %s", qfpathname); 396 close(fd); 397 free(qup); 398 continue; 399 } 400 close(fd); | 394 qup->qf = qf; 395 strncpy(qup->fsname, fs->fs_file, sizeof(qup->fsname)); 396 if (quota_read(qf, &qup->dqblk, id) == -1) { 397 warn("cannot read quotas on %s", fs->fs_file); 398 freeprivs(qup); 399 continue; |
401 } | 400 } |
402 strcpy(qup->qfname, qfpathname); 403 strcpy(qup->fsname, fs->fs_file); | |
404 if (quphead == NULL) 405 quphead = qup; 406 else 407 quptail->next = qup; 408 quptail = qup; 409 qup->next = 0; 410 } | 401 if (quphead == NULL) 402 quphead = qup; 403 else 404 quptail->next = qup; 405 quptail = qup; 406 qup->next = 0; 407 } |
408 if (quphead == NULL) { 409 warnx("No quotas on %s", fspath ? fspath : "any filesystems"); 410 } |
|
411 endfsent(); 412 return (quphead); 413} 414 415/* 416 * Store the requested quota information. 417 */ 418void | 411 endfsent(); 412 return (quphead); 413} 414 415/* 416 * Store the requested quota information. 417 */ 418void |
419putprivs(long id, int quotatype, struct quotause *quplist) | 419putprivs(long id, struct quotause *quplist) |
420{ 421 struct quotause *qup; | 420{ 421 struct quotause *qup; |
422 int qcmd, fd; 423 struct dqblk dqbuf; | |
424 | 422 |
425 qcmd = QCMD(Q_SETQUOTA, quotatype); 426 for (qup = quplist; qup; qup = qup->next) { 427 if (quotactl(qup->fsname, qcmd, id, &qup->dqblk) == 0) 428 continue; 429 if ((fd = open(qup->qfname, O_RDWR)) < 0) { 430 warn("%s", qup->qfname); 431 continue; 432 } 433 if (lseek(fd, (off_t)id * sizeof(struct dqblk), L_SET) < 0) { 434 warn("seek error on %s", qup->qfname); 435 close(fd); 436 continue; 437 } 438 switch (read(fd, &dqbuf, sizeof(struct dqblk))) { 439 case 0: /* EOF */ 440 /* 441 * Convert implicit 0 quota (EOF) 442 * into an explicit one (zero'ed dqblk) 443 */ 444 bzero(&dqbuf, sizeof(struct dqblk)); 445 break; 446 447 case sizeof(struct dqblk): /* OK */ 448 break; 449 450 default: /* ERROR */ 451 warn("read error in %s", qup->qfname); 452 close(fd); 453 continue; 454 } 455 /* 456 * Reset time limit if have a soft limit and were 457 * previously under it, but are now over it 458 * or if there previously was no soft limit, but 459 * now have one and are over it. 460 */ 461 if (dqbuf.dqb_bsoftlimit && id != 0 && 462 dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit && 463 dqbuf.dqb_curblocks >= qup->dqblk.dqb_bsoftlimit) 464 qup->dqblk.dqb_btime = 0; 465 if (dqbuf.dqb_bsoftlimit == 0 && id != 0 && 466 dqbuf.dqb_curblocks >= qup->dqblk.dqb_bsoftlimit) 467 qup->dqblk.dqb_btime = 0; 468 if (dqbuf.dqb_isoftlimit && id != 0 && 469 dqbuf.dqb_curinodes < dqbuf.dqb_isoftlimit && 470 dqbuf.dqb_curinodes >= qup->dqblk.dqb_isoftlimit) 471 qup->dqblk.dqb_itime = 0; 472 if (dqbuf.dqb_isoftlimit == 0 && id !=0 && 473 dqbuf.dqb_curinodes >= qup->dqblk.dqb_isoftlimit) 474 qup->dqblk.dqb_itime = 0; 475 qup->dqblk.dqb_curinodes = dqbuf.dqb_curinodes; 476 qup->dqblk.dqb_curblocks = dqbuf.dqb_curblocks; 477 if (lseek(fd, (off_t)id * sizeof(struct dqblk), L_SET) < 0) { 478 warn("seek error on %s", qup->qfname); 479 close(fd); 480 continue; 481 } 482 if (write(fd, &qup->dqblk, sizeof (struct dqblk)) != 483 sizeof (struct dqblk)) { 484 warn("%s", qup->qfname); 485 } 486 close(fd); 487 } | 423 for (qup = quplist; qup; qup = qup->next) 424 if (quota_write_limits(qup->qf, &qup->dqblk, id) == -1) 425 warn("%s", qup->fsname); |
488} 489 490/* 491 * Take a list of priviledges and get it edited. 492 */ 493int 494editit(char *tmpf) 495{ --- 43 unchanged lines hidden (view full) --- 539 FILE *fd; 540 541 ftruncate(outfd, 0); 542 lseek(outfd, 0, L_SET); 543 if ((fd = fdopen(dup(outfd), "w")) == NULL) 544 err(1, "%s", tmpfil); 545 fprintf(fd, "Quotas for %s %s:\n", qfextension[quotatype], name); 546 for (qup = quplist; qup; qup = qup->next) { | 426} 427 428/* 429 * Take a list of priviledges and get it edited. 430 */ 431int 432editit(char *tmpf) 433{ --- 43 unchanged lines hidden (view full) --- 477 FILE *fd; 478 479 ftruncate(outfd, 0); 480 lseek(outfd, 0, L_SET); 481 if ((fd = fdopen(dup(outfd), "w")) == NULL) 482 err(1, "%s", tmpfil); 483 fprintf(fd, "Quotas for %s %s:\n", qfextension[quotatype], name); 484 for (qup = quplist; qup; qup = qup->next) { |
547 fprintf(fd, "%s: %s %lu, limits (soft = %lu, hard = %lu)\n", 548 qup->fsname, "kbytes in use:", 549 (unsigned long)(dbtob(qup->dqblk.dqb_curblocks) / 1024), 550 (unsigned long)(dbtob(qup->dqblk.dqb_bsoftlimit) / 1024), 551 (unsigned long)(dbtob(qup->dqblk.dqb_bhardlimit) / 1024)); 552 fprintf(fd, "%s %lu, limits (soft = %lu, hard = %lu)\n", 553 "\tinodes in use:", 554 (unsigned long)qup->dqblk.dqb_curinodes, 555 (unsigned long)qup->dqblk.dqb_isoftlimit, 556 (unsigned long)qup->dqblk.dqb_ihardlimit); | 485 fprintf(fd, "%s: in use: %s, ", qup->fsname, 486 fmthumanvalblks(qup->dqblk.dqb_curblocks)); 487 fprintf(fd, "limits (soft = %s, ", 488 fmthumanvalblks(qup->dqblk.dqb_bsoftlimit)); 489 fprintf(fd, "hard = %s)\n", 490 fmthumanvalblks(qup->dqblk.dqb_bhardlimit)); 491 fprintf(fd, "\tinodes in use: %s, ", 492 fmthumanvalinos(qup->dqblk.dqb_curinodes)); 493 fprintf(fd, "limits (soft = %s, ", 494 fmthumanvalinos(qup->dqblk.dqb_isoftlimit)); 495 fprintf(fd, "hard = %s)\n", 496 fmthumanvalinos(qup->dqblk.dqb_ihardlimit)); |
557 } 558 fclose(fd); 559 return (1); 560} 561 | 497 } 498 fclose(fd); 499 return (1); 500} 501 |
502char * 503fmthumanvalblks(int64_t blocks) 504{ 505 static char numbuf[20]; 506 507 if (hflag) { 508 humanize_number(numbuf, blocks < 0 ? 7 : 6, 509 dbtob(blocks), "", HN_AUTOSCALE, HN_NOSPACE); 510 return (numbuf); 511 } 512 snprintf(numbuf, sizeof(numbuf), "%juk", (uintmax_t)dbtokb(blocks)); 513 return(numbuf); 514} 515 516char * 517fmthumanvalinos(int64_t inos) 518{ 519 static char numbuf[20]; 520 521 if (hflag) { 522 humanize_number(numbuf, inos < 0 ? 7 : 6, 523 inos, "", HN_AUTOSCALE, HN_NOSPACE | HN_DIVISOR_1000); 524 return (numbuf); 525 } 526 snprintf(numbuf, sizeof(numbuf), "%ju", (uintmax_t)inos); 527 return(numbuf); 528} 529 |
|
562/* 563 * Merge changes to an ASCII file into a quotause list. 564 */ 565int 566readprivs(struct quotause *quplist, char *inname) 567{ 568 struct quotause *qup; 569 FILE *fd; | 530/* 531 * Merge changes to an ASCII file into a quotause list. 532 */ 533int 534readprivs(struct quotause *quplist, char *inname) 535{ 536 struct quotause *qup; 537 FILE *fd; |
570 unsigned long bhardlimit, bsoftlimit, curblocks; 571 unsigned long ihardlimit, isoftlimit, curinodes; | 538 uintmax_t hardlimit, softlimit, curitems; 539 char hardunits, softunits, curitemunits; |
572 int cnt; 573 char *cp; 574 struct dqblk dqblk; 575 char *fsp, line1[BUFSIZ], line2[BUFSIZ]; 576 577 fd = fopen(inname, "r"); 578 if (fd == NULL) { 579 warnx("can't re-read temp file!!"); --- 9 unchanged lines hidden (view full) --- 589 warnx("%s: bad format", line1); 590 return (0); 591 } 592 if ((cp = strtok((char *)0, "\n")) == NULL) { 593 warnx("%s: %s: bad format", fsp, &fsp[strlen(fsp) + 1]); 594 return (0); 595 } 596 cnt = sscanf(cp, | 540 int cnt; 541 char *cp; 542 struct dqblk dqblk; 543 char *fsp, line1[BUFSIZ], line2[BUFSIZ]; 544 545 fd = fopen(inname, "r"); 546 if (fd == NULL) { 547 warnx("can't re-read temp file!!"); --- 9 unchanged lines hidden (view full) --- 557 warnx("%s: bad format", line1); 558 return (0); 559 } 560 if ((cp = strtok((char *)0, "\n")) == NULL) { 561 warnx("%s: %s: bad format", fsp, &fsp[strlen(fsp) + 1]); 562 return (0); 563 } 564 cnt = sscanf(cp, |
597 " kbytes in use: %lu, limits (soft = %lu, hard = %lu)", 598 &curblocks, &bsoftlimit, &bhardlimit); 599 if (cnt != 3) { | 565 " in use: %ju%c, limits (soft = %ju%c, hard = %ju%c)", 566 &curitems, &curitemunits, &softlimit, &softunits, 567 &hardlimit, &hardunits); 568 /* 569 * The next three check for old-style input formats. 570 */ 571 if (cnt != 6) 572 cnt = sscanf(cp, 573 " in use: %ju%c, limits (soft = %ju%c hard = %ju%c", 574 &curitems, &curitemunits, &softlimit, 575 &softunits, &hardlimit, &hardunits); 576 if (cnt != 6) 577 cnt = sscanf(cp, 578 " in use: %ju%c, limits (soft = %ju%c hard = %ju%c)", 579 &curitems, &curitemunits, &softlimit, 580 &softunits, &hardlimit, &hardunits); 581 if (cnt != 6) 582 cnt = sscanf(cp, 583 " in use: %ju%c, limits (soft = %ju%c, hard = %ju%c", 584 &curitems, &curitemunits, &softlimit, 585 &softunits, &hardlimit, &hardunits); 586 if (cnt != 6) { |
600 warnx("%s:%s: bad format", fsp, cp); 601 return (0); 602 } | 587 warnx("%s:%s: bad format", fsp, cp); 588 return (0); 589 } |
603 dqblk.dqb_curblocks = btodb((off_t)curblocks * 1024); 604 dqblk.dqb_bsoftlimit = btodb((off_t)bsoftlimit * 1024); 605 dqblk.dqb_bhardlimit = btodb((off_t)bhardlimit * 1024); | 590 dqblk.dqb_curblocks = cvtblkval(curitems, curitemunits, 591 "current block count"); 592 dqblk.dqb_bsoftlimit = cvtblkval(softlimit, softunits, 593 "block soft limit"); 594 dqblk.dqb_bhardlimit = cvtblkval(hardlimit, hardunits, 595 "block hard limit"); |
606 if ((cp = strtok(line2, "\n")) == NULL) { 607 warnx("%s: %s: bad format", fsp, line2); 608 return (0); 609 } | 596 if ((cp = strtok(line2, "\n")) == NULL) { 597 warnx("%s: %s: bad format", fsp, line2); 598 return (0); 599 } |
610 cnt = sscanf(cp, 611 "\tinodes in use: %lu, limits (soft = %lu, hard = %lu)", 612 &curinodes, &isoftlimit, &ihardlimit); 613 if (cnt != 3) { 614 warnx("%s: %s: bad format", fsp, line2); | 600 cnt = sscanf(&cp[7], 601 " in use: %ju%c limits (soft = %ju%c, hard = %ju%c)", 602 &curitems, &curitemunits, &softlimit, 603 &softunits, &hardlimit, &hardunits); 604 /* 605 * The next three check for old-style input formats. 606 */ 607 if (cnt != 6) 608 cnt = sscanf(&cp[7], 609 " in use: %ju%c limits (soft = %ju%c hard = %ju%c", 610 &curitems, &curitemunits, &softlimit, 611 &softunits, &hardlimit, &hardunits); 612 if (cnt != 6) 613 cnt = sscanf(&cp[7], 614 " in use: %ju%c limits (soft = %ju%c hard = %ju%c)", 615 &curitems, &curitemunits, &softlimit, 616 &softunits, &hardlimit, &hardunits); 617 if (cnt != 6) 618 cnt = sscanf(&cp[7], 619 " in use: %ju%c limits (soft = %ju%c, hard = %ju%c", 620 &curitems, &curitemunits, &softlimit, 621 &softunits, &hardlimit, &hardunits); 622 if (cnt != 6) { 623 warnx("%s: %s: bad format cnt %d", fsp, &cp[7], cnt); |
615 return (0); 616 } | 624 return (0); 625 } |
617 dqblk.dqb_curinodes = curinodes; 618 dqblk.dqb_isoftlimit = isoftlimit; 619 dqblk.dqb_ihardlimit = ihardlimit; | 626 dqblk.dqb_curinodes = cvtinoval(curitems, curitemunits, 627 "current inode count"); 628 dqblk.dqb_isoftlimit = cvtinoval(softlimit, softunits, 629 "inode soft limit"); 630 dqblk.dqb_ihardlimit = cvtinoval(hardlimit, hardunits, 631 "inode hard limit"); |
620 for (qup = quplist; qup; qup = qup->next) { 621 if (strcmp(fsp, qup->fsname)) 622 continue; 623 /* 624 * Cause time limit to be reset when the quota 625 * is next used if previously had no soft limit 626 * or were under it, but now have a soft limit 627 * and are over it. --- 10 unchanged lines hidden (view full) --- 638 qup->dqblk.dqb_curinodes < 639 qup->dqblk.dqb_isoftlimit)) 640 qup->dqblk.dqb_itime = 0; 641 qup->dqblk.dqb_bsoftlimit = dqblk.dqb_bsoftlimit; 642 qup->dqblk.dqb_bhardlimit = dqblk.dqb_bhardlimit; 643 qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit; 644 qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit; 645 qup->flags |= FOUND; | 632 for (qup = quplist; qup; qup = qup->next) { 633 if (strcmp(fsp, qup->fsname)) 634 continue; 635 /* 636 * Cause time limit to be reset when the quota 637 * is next used if previously had no soft limit 638 * or were under it, but now have a soft limit 639 * and are over it. --- 10 unchanged lines hidden (view full) --- 650 qup->dqblk.dqb_curinodes < 651 qup->dqblk.dqb_isoftlimit)) 652 qup->dqblk.dqb_itime = 0; 653 qup->dqblk.dqb_bsoftlimit = dqblk.dqb_bsoftlimit; 654 qup->dqblk.dqb_bhardlimit = dqblk.dqb_bhardlimit; 655 qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit; 656 qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit; 657 qup->flags |= FOUND; |
646 if (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks && 647 dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes) | 658 /* Humanized input returns only approximate counts */ 659 if (hflag || 660 (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks && 661 dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes)) |
648 break; 649 warnx("%s: cannot change current allocation", fsp); 650 break; 651 } 652 } 653 fclose(fd); 654 /* 655 * Disable quotas for any filesystems that have not been found. --- 42 unchanged lines hidden (view full) --- 698 */ 699int 700readtimes(struct quotause *quplist, char *inname) 701{ 702 struct quotause *qup; 703 FILE *fd; 704 int cnt; 705 char *cp; | 662 break; 663 warnx("%s: cannot change current allocation", fsp); 664 break; 665 } 666 } 667 fclose(fd); 668 /* 669 * Disable quotas for any filesystems that have not been found. --- 42 unchanged lines hidden (view full) --- 712 */ 713int 714readtimes(struct quotause *quplist, char *inname) 715{ 716 struct quotause *qup; 717 FILE *fd; 718 int cnt; 719 char *cp; |
706 time_t itime, btime, iseconds, bseconds; 707 long l_itime, l_btime; | 720 uintmax_t itime, btime, iseconds, bseconds; |
708 char *fsp, bunits[10], iunits[10], line1[BUFSIZ]; 709 710 fd = fopen(inname, "r"); 711 if (fd == NULL) { 712 warnx("can't re-read temp file!!"); 713 return (0); 714 } 715 /* --- 6 unchanged lines hidden (view full) --- 722 warnx("%s: bad format", line1); 723 return (0); 724 } 725 if ((cp = strtok((char *)0, "\n")) == NULL) { 726 warnx("%s: %s: bad format", fsp, &fsp[strlen(fsp) + 1]); 727 return (0); 728 } 729 cnt = sscanf(cp, | 721 char *fsp, bunits[10], iunits[10], line1[BUFSIZ]; 722 723 fd = fopen(inname, "r"); 724 if (fd == NULL) { 725 warnx("can't re-read temp file!!"); 726 return (0); 727 } 728 /* --- 6 unchanged lines hidden (view full) --- 735 warnx("%s: bad format", line1); 736 return (0); 737 } 738 if ((cp = strtok((char *)0, "\n")) == NULL) { 739 warnx("%s: %s: bad format", fsp, &fsp[strlen(fsp) + 1]); 740 return (0); 741 } 742 cnt = sscanf(cp, |
730 " block grace period: %ld %s file grace period: %ld %s", 731 &l_btime, bunits, &l_itime, iunits); | 743 " block grace period: %ju %s file grace period: %ju %s", 744 &btime, bunits, &itime, iunits); |
732 if (cnt != 4) { 733 warnx("%s:%s: bad format", fsp, cp); 734 return (0); 735 } | 745 if (cnt != 4) { 746 warnx("%s:%s: bad format", fsp, cp); 747 return (0); 748 } |
736 btime = l_btime; 737 itime = l_itime; | |
738 if (cvtatos(btime, bunits, &bseconds) == 0) 739 return (0); 740 if (cvtatos(itime, iunits, &iseconds) == 0) 741 return (0); 742 for (qup = quplist; qup; qup = qup->next) { 743 if (strcmp(fsp, qup->fsname)) 744 continue; 745 qup->dqblk.dqb_btime = bseconds; --- 17 unchanged lines hidden (view full) --- 763 } 764 return (1); 765} 766 767/* 768 * Convert seconds to ASCII times. 769 */ 770char * | 749 if (cvtatos(btime, bunits, &bseconds) == 0) 750 return (0); 751 if (cvtatos(itime, iunits, &iseconds) == 0) 752 return (0); 753 for (qup = quplist; qup; qup = qup->next) { 754 if (strcmp(fsp, qup->fsname)) 755 continue; 756 qup->dqblk.dqb_btime = bseconds; --- 17 unchanged lines hidden (view full) --- 774 } 775 return (1); 776} 777 778/* 779 * Convert seconds to ASCII times. 780 */ 781char * |
771cvtstoa(time_t secs) | 782cvtstoa(uint64_t secs) |
772{ 773 static char buf[20]; 774 775 if (secs % (24 * 60 * 60) == 0) { 776 secs /= 24 * 60 * 60; | 783{ 784 static char buf[20]; 785 786 if (secs % (24 * 60 * 60) == 0) { 787 secs /= 24 * 60 * 60; |
777 sprintf(buf, "%ld day%s", (long)secs, secs == 1 ? "" : "s"); | 788 sprintf(buf, "%ju day%s", (uintmax_t)secs, 789 secs == 1 ? "" : "s"); |
778 } else if (secs % (60 * 60) == 0) { 779 secs /= 60 * 60; | 790 } else if (secs % (60 * 60) == 0) { 791 secs /= 60 * 60; |
780 sprintf(buf, "%ld hour%s", (long)secs, secs == 1 ? "" : "s"); | 792 sprintf(buf, "%ju hour%s", (uintmax_t)secs, 793 secs == 1 ? "" : "s"); |
781 } else if (secs % 60 == 0) { 782 secs /= 60; | 794 } else if (secs % 60 == 0) { 795 secs /= 60; |
783 sprintf(buf, "%ld minute%s", (long)secs, secs == 1 ? "" : "s"); | 796 sprintf(buf, "%ju minute%s", (uintmax_t)secs, 797 secs == 1 ? "" : "s"); |
784 } else | 798 } else |
785 sprintf(buf, "%ld second%s", (long)secs, secs == 1 ? "" : "s"); | 799 sprintf(buf, "%ju second%s", (uintmax_t)secs, 800 secs == 1 ? "" : "s"); |
786 return (buf); 787} 788 789/* 790 * Convert ASCII input times to seconds. 791 */ 792int | 801 return (buf); 802} 803 804/* 805 * Convert ASCII input times to seconds. 806 */ 807int |
793cvtatos(time_t period, char *units, time_t *seconds) | 808cvtatos(uint64_t period, char *units, uint64_t *seconds) |
794{ 795 796 if (bcmp(units, "second", 6) == 0) 797 *seconds = period; 798 else if (bcmp(units, "minute", 6) == 0) 799 *seconds = period * 60; 800 else if (bcmp(units, "hour", 4) == 0) 801 *seconds = period * 60 * 60; 802 else if (bcmp(units, "day", 3) == 0) 803 *seconds = period * 24 * 60 * 60; 804 else { | 809{ 810 811 if (bcmp(units, "second", 6) == 0) 812 *seconds = period; 813 else if (bcmp(units, "minute", 6) == 0) 814 *seconds = period * 60; 815 else if (bcmp(units, "hour", 4) == 0) 816 *seconds = period * 60 * 60; 817 else if (bcmp(units, "day", 3) == 0) 818 *seconds = period * 24 * 60 * 60; 819 else { |
805 printf("%s: bad units, specify %s\n", units, | 820 warnx("%s: bad units, specify %s\n", units, |
806 "days, hours, minutes, or seconds"); 807 return (0); 808 } 809 return (1); 810} 811 812/* | 821 "days, hours, minutes, or seconds"); 822 return (0); 823 } 824 return (1); 825} 826 827/* |
828 * Convert a limit to number of disk blocks. 829 */ 830uint64_t 831cvtblkval(uint64_t limit, char units, const char *itemname) 832{ 833 834 switch(units) { 835 case 'B': 836 case 'b': 837 limit = btodb(limit); 838 break; 839 case '\0': /* historic behavior */ 840 case ',': /* historic behavior */ 841 case ')': /* historic behavior */ 842 case 'K': 843 case 'k': 844 limit *= btodb(1024); 845 break; 846 case 'M': 847 case 'm': 848 limit *= btodb(1048576); 849 break; 850 case 'G': 851 case 'g': 852 limit *= btodb(1073741824); 853 break; 854 case 'T': 855 case 't': 856 limit *= btodb(1099511627776); 857 break; 858 case 'P': 859 case 'p': 860 limit *= btodb(1125899906842624); 861 break; 862 case 'E': 863 case 'e': 864 limit *= btodb(1152921504606846976); 865 break; 866 case ' ': 867 errx(2, "No space permitted between value and units for %s\n", 868 itemname); 869 break; 870 default: 871 errx(2, "%ju%c: unknown units for %s, specify " 872 "none, K, M, G, T, P, or E\n", 873 (uintmax_t)limit, units, itemname); 874 break; 875 } 876 return (limit); 877} 878 879/* 880 * Convert a limit to number of inodes. 881 */ 882uint64_t 883cvtinoval(uint64_t limit, char units, const char *itemname) 884{ 885 886 switch(units) { 887 case 'B': 888 case 'b': 889 case '\0': /* historic behavior */ 890 case ',': /* historic behavior */ 891 case ')': /* historic behavior */ 892 break; 893 case 'K': 894 case 'k': 895 limit *= 1000; 896 break; 897 case 'M': 898 case 'm': 899 limit *= 1000000; 900 break; 901 case 'G': 902 case 'g': 903 limit *= 1000000000; 904 break; 905 case 'T': 906 case 't': 907 limit *= 1000000000000; 908 break; 909 case 'P': 910 case 'p': 911 limit *= 1000000000000000; 912 break; 913 case 'E': 914 case 'e': 915 limit *= 1000000000000000000; 916 break; 917 case ' ': 918 errx(2, "No space permitted between value and units for %s\n", 919 itemname); 920 break; 921 default: 922 errx(2, "%ju%c: unknown units for %s, specify " 923 "none, K, M, G, T, P, or E\n", 924 (uintmax_t)limit, units, itemname); 925 break; 926 } 927 return (limit); 928} 929 930/* |
|
813 * Free a list of quotause structures. 814 */ 815void 816freeprivs(struct quotause *quplist) 817{ 818 struct quotause *qup, *nextqup; 819 820 for (qup = quplist; qup; qup = nextqup) { | 931 * Free a list of quotause structures. 932 */ 933void 934freeprivs(struct quotause *quplist) 935{ 936 struct quotause *qup, *nextqup; 937 938 for (qup = quplist; qup; qup = nextqup) { |
939 quota_close(qup->qf); |
|
821 nextqup = qup->next; 822 free(qup); 823 } 824} 825 826/* 827 * Check whether a string is completely composed of digits. 828 */ --- 4 unchanged lines hidden (view full) --- 833 834 c = *s++; 835 do { 836 if (!isdigit(c)) 837 return (0); 838 } while ((c = *s++)); 839 return (1); 840} | 940 nextqup = qup->next; 941 free(qup); 942 } 943} 944 945/* 946 * Check whether a string is completely composed of digits. 947 */ --- 4 unchanged lines hidden (view full) --- 952 953 c = *s++; 954 do { 955 if (!isdigit(c)) 956 return (0); 957 } while ((c = *s++)); 958 return (1); 959} |
841 842/* 843 * Check to see if a particular quota is to be enabled. 844 */ 845int 846hasquota(struct fstab *fs, int type, char **qfnamep) 847{ 848 char *opt; 849 char *cp; 850 struct statfs sfb; 851 static char initname, usrname[100], grpname[100]; 852 static char buf[BUFSIZ]; 853 854 if (!initname) { 855 (void)snprintf(usrname, sizeof(usrname), "%s%s", 856 qfextension[USRQUOTA], qfname); 857 (void)snprintf(grpname, sizeof(grpname), "%s%s", 858 qfextension[GRPQUOTA], qfname); 859 initname = 1; 860 } 861 strcpy(buf, fs->fs_mntops); 862 for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { 863 if ((cp = index(opt, '='))) 864 *cp++ = '\0'; 865 if (type == USRQUOTA && strcmp(opt, usrname) == 0) 866 break; 867 if (type == GRPQUOTA && strcmp(opt, grpname) == 0) 868 break; 869 } 870 if (!opt) 871 return (0); 872 if (cp) 873 *qfnamep = cp; 874 else { 875 (void)snprintf(buf, sizeof(buf), "%s/%s.%s", fs->fs_file, 876 qfname, qfextension[type]); 877 *qfnamep = buf; 878 } 879 if (statfs(fs->fs_file, &sfb) != 0) { 880 warn("cannot statfs mount point %s", fs->fs_file); 881 return (0); 882 } 883 if (strcmp(fs->fs_file, sfb.f_mntonname)) { 884 warnx("%s not mounted for %s quotas", fs->fs_file, 885 type == USRQUOTA ? "user" : "group"); 886 sleep(3); 887 return (0); 888 } 889 return (1); 890} | |