Mon Jan 30 19:19:20 2012 UTC ()
Remove dependence on quotaprop.h, also quotautil.c (no longer used).

Like repquota, compile in the number of object types for now because
making it support an arbitrary number would take some hacking.


(dholland)
diff -r1.9 -r1.10 src/usr.sbin/edquota/Makefile
diff -r1.45 -r1.46 src/usr.sbin/edquota/edquota.c

cvs diff -r1.9 -r1.10 src/usr.sbin/edquota/Makefile (expand / switch to unified diff)

--- src/usr.sbin/edquota/Makefile 2012/01/30 19:16:36 1.9
+++ src/usr.sbin/edquota/Makefile 2012/01/30 19:19:20 1.10
@@ -1,20 +1,18 @@ @@ -1,20 +1,18 @@
1# from: @(#)Makefile 8.1 (Berkeley) 6/6/93 1# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
2# $NetBSD: Makefile,v 1.9 2012/01/30 19:16:36 dholland Exp $ 2# $NetBSD: Makefile,v 1.10 2012/01/30 19:19:20 dholland Exp $
3 3
4.include <bsd.own.mk> 4.include <bsd.own.mk>
5 5
6WARNS ?= 4 6WARNS ?= 4
7PROG= edquota 7PROG= edquota
8SRCS= edquota.c 8SRCS= edquota.c
9MAN= edquota.8 9MAN= edquota.8
10 10
11CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${NETBSDSRCDIR}/usr.bin/quota 11CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${NETBSDSRCDIR}/usr.bin/quota
12DPADD= ${LIBQUOTA} ${LIBPROP} ${LIBRPCSVC} 12DPADD= ${LIBQUOTA} ${LIBPROP} ${LIBRPCSVC}
13LDADD= -lquota -lprop -lrpcsvc 13LDADD= -lquota -lprop -lrpcsvc
14 14
15.PATH: ${NETBSDSRCDIR}/usr.bin/quota 15.PATH: ${NETBSDSRCDIR}/usr.bin/quota
16SRCS+= printquota.c quotautil.c 16SRCS+= printquota.c
17.PATH: ${NETBSDSRCDIR}/sys/ufs/ufs  
18SRCS+= quota1_subr.c 
19 17
20.include <bsd.prog.mk> 18.include <bsd.prog.mk>

cvs diff -r1.45 -r1.46 src/usr.sbin/edquota/edquota.c (expand / switch to unified diff)

--- src/usr.sbin/edquota/edquota.c 2012/01/30 19:18:36 1.45
+++ src/usr.sbin/edquota/edquota.c 2012/01/30 19:19:20 1.46
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: edquota.c,v 1.45 2012/01/30 19:18:36 dholland Exp $ */ 1/* $NetBSD: edquota.c,v 1.46 2012/01/30 19:19:20 dholland Exp $ */
2/* 2/*
3 * Copyright (c) 1980, 1990, 1993 3 * Copyright (c) 1980, 1990, 1993
4 * The Regents of the University of California. All rights reserved. 4 * The Regents of the University of California. All rights reserved.
5 * 5 *
6 * This code is derived from software contributed to Berkeley by 6 * This code is derived from software contributed to Berkeley by
7 * Robert Elz at The University of Melbourne. 7 * Robert Elz at The University of Melbourne.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -31,97 +31,100 @@ @@ -31,97 +31,100 @@
31 * SUCH DAMAGE. 31 * SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35#ifndef lint 35#ifndef lint
36__COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\ 36__COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\
37 The Regents of the University of California. All rights reserved."); 37 The Regents of the University of California. All rights reserved.");
38#endif /* not lint */ 38#endif /* not lint */
39 39
40#ifndef lint 40#ifndef lint
41#if 0 41#if 0
42static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95"; 42static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95";
43#else 43#else
44__RCSID("$NetBSD: edquota.c,v 1.45 2012/01/30 19:18:36 dholland Exp $"); 44__RCSID("$NetBSD: edquota.c,v 1.46 2012/01/30 19:19:20 dholland Exp $");
45#endif 45#endif
46#endif /* not lint */ 46#endif /* not lint */
47 47
48/* 48/*
49 * Disk quota editor. 49 * Disk quota editor.
50 */ 50 */
51#include <sys/param.h> 51#include <sys/param.h>
52#include <sys/stat.h> 52#include <sys/stat.h>
53#include <sys/file.h> 53#include <sys/file.h>
54#include <sys/wait.h> 54#include <sys/wait.h>
55#include <sys/queue.h> 55#include <sys/queue.h>
56#include <sys/types.h> 56#include <sys/types.h>
57#include <sys/statvfs.h> 57#include <sys/statvfs.h>
58 58
59#include <quota.h> 59#include <quota.h>
60#include <quota/quotaprop.h> 
61#include <quota/quota.h> 
62#include <ufs/ufs/quota1.h> 
63 60
64#include <assert.h> 61#include <assert.h>
65#include <err.h> 62#include <err.h>
66#include <errno.h> 63#include <errno.h>
67#include <fstab.h> 64#include <fstab.h>
68#include <pwd.h> 65#include <pwd.h>
69#include <grp.h> 66#include <grp.h>
70#include <ctype.h> 67#include <ctype.h>
71#include <signal.h> 68#include <signal.h>
72#include <stdbool.h> 69#include <stdbool.h>
73#include <stdio.h> 70#include <stdio.h>
74#include <stdlib.h> 71#include <stdlib.h>
75#include <string.h> 72#include <string.h>
76#include <unistd.h> 73#include <unistd.h>
77 74
78#include "printquota.h" 75#include "printquota.h"
79#include "quotautil.h" 
80 76
81#include "pathnames.h" 77#include "pathnames.h"
82 78
 79/*
 80 * XXX. Ideally we shouldn't compile this in, but it'll take some
 81 * reworking to avoid it and it'll be ok for now.
 82 */
 83#define EDQUOTA_NUMOBJTYPES 2
 84
83#if 0 85#if 0
84static const char *quotagroup = QUOTAGROUP; 86static const char *quotagroup = QUOTAGROUP;
85#endif 87#endif
86 88
87#define MAX_TMPSTR (100+MAXPATHLEN) 89#define MAX_TMPSTR (100+MAXPATHLEN)
88 90
89/* flags for quotause */ 91/* flags for quotause */
90#define FOUND 0x01 92#define FOUND 0x01
91#define XGRACE 0x02 /* extended grace periods (per-id) */ 93#define XGRACE 0x02 /* extended grace periods (per-id) */
92#define DEFAULT 0x04 94#define DEFAULT 0x04
93 95
94struct quotause { 96struct quotause {
95 struct quotause *next; 97 struct quotause *next;
96 long flags; 98 long flags;
97 struct quotaval qv[QUOTA_NLIMITS]; 99 struct quotaval qv[EDQUOTA_NUMOBJTYPES];
98 char fsname[MAXPATHLEN + 1]; 100 char fsname[MAXPATHLEN + 1];
99 char implementation[32]; 101 char implementation[32];
100 char *qfname; 102 char *qfname;
101}; 103};
102 104
103struct quotalist { 105struct quotalist {
104 struct quotause *head; 106 struct quotause *head;
105 struct quotause *tail; 107 struct quotause *tail;
 108 char *idtypename;
106}; 109};
107 110
108static void usage(void) __dead; 111static void usage(void) __dead;
109 112
110static int Hflag = 0; 113static int Hflag = 0;
111 114
112/* more compact form of constants */ 115/* more compact form of constants */
113#define QL_BLK QUOTA_LIMIT_BLOCK 116#define QO_BLK QUOTA_OBJTYPE_BLOCKS
114#define QL_FL QUOTA_LIMIT_FILE 117#define QO_FL QUOTA_OBJTYPE_FILES
115 118
116//////////////////////////////////////////////////////////// 119////////////////////////////////////////////////////////////
117// support code 120// support code
118 121
119/* 122/*
120 * This routine converts a name for a particular quota class to 123 * This routine converts a name for a particular quota class to
121 * an identifier. This routine must agree with the kernel routine 124 * an identifier. This routine must agree with the kernel routine
122 * getinoquota as to the interpretation of quota classes. 125 * getinoquota as to the interpretation of quota classes.
123 */ 126 */
124static int 127static int
125getidbyname(const char *name, int idtype) 128getidbyname(const char *name, int idtype)
126{ 129{
127 struct passwd *pw; 130 struct passwd *pw;
@@ -191,42 +194,44 @@ quotause_destroy(struct quotause *qup) @@ -191,42 +194,44 @@ quotause_destroy(struct quotause *qup)
191 */ 194 */
192static struct quotalist * 195static struct quotalist *
193quotalist_create(void) 196quotalist_create(void)
194{ 197{
195 struct quotalist *qlist; 198 struct quotalist *qlist;
196 199
197 qlist = malloc(sizeof(*qlist)); 200 qlist = malloc(sizeof(*qlist));
198 if (qlist == NULL) { 201 if (qlist == NULL) {
199 err(1, "malloc"); 202 err(1, "malloc");
200 } 203 }
201 204
202 qlist->head = NULL; 205 qlist->head = NULL;
203 qlist->tail = NULL; 206 qlist->tail = NULL;
 207 qlist->idtypename = NULL;
204 208
205 return qlist; 209 return qlist;
206} 210}
207 211
208/* 212/*
209 * Free a list of quotause structures. 213 * Free a list of quotause structures.
210 */ 214 */
211static void 215static void
212quotalist_destroy(struct quotalist *qlist) 216quotalist_destroy(struct quotalist *qlist)
213{ 217{
214 struct quotause *qup, *nextqup; 218 struct quotause *qup, *nextqup;
215 219
216 for (qup = qlist->head; qup; qup = nextqup) { 220 for (qup = qlist->head; qup; qup = nextqup) {
217 nextqup = qup->next; 221 nextqup = qup->next;
218 quotause_destroy(qup); 222 quotause_destroy(qup);
219 } 223 }
 224 free(qlist->idtypename);
220 free(qlist); 225 free(qlist);
221} 226}
222 227
223#if 0 228#if 0
224static bool 229static bool
225quotalist_empty(struct quotalist *qlist) 230quotalist_empty(struct quotalist *qlist)
226{ 231{
227 return qlist->head == NULL; 232 return qlist->head == NULL;
228} 233}
229#endif 234#endif
230 235
231static void 236static void
232quotalist_append(struct quotalist *qlist, struct quotause *qup) 237quotalist_append(struct quotalist *qlist, struct quotause *qup)
@@ -352,55 +357,65 @@ dogetprivs2(struct quotahandle *qh, int  @@ -352,55 +357,65 @@ dogetprivs2(struct quotahandle *qh, int
352 qk.qk_id = defaultq ? QUOTA_DEFAULTID : id; 357 qk.qk_id = defaultq ? QUOTA_DEFAULTID : id;
353 qk.qk_objtype = objtype; 358 qk.qk_objtype = objtype;
354 if (quota_get(qh, &qk, &qup->qv[objtype])) { 359 if (quota_get(qh, &qk, &qup->qv[objtype])) {
355 /* no entry, get default entry */ 360 /* no entry, get default entry */
356 qk.qk_id = QUOTA_DEFAULTID; 361 qk.qk_id = QUOTA_DEFAULTID;
357 if (quota_get(qh, &qk, &qup->qv[objtype])) { 362 if (quota_get(qh, &qk, &qup->qv[objtype])) {
358 return -1; 363 return -1;
359 } 364 }
360 } 365 }
361 return 0; 366 return 0;
362} 367}
363 368
364static struct quotause * 369static struct quotause *
365getprivs2(long id, int idtype, const char *filesys, int defaultq) 370getprivs2(long id, int idtype, const char *filesys, int defaultq,
 371 char **idtypename_p)
366{ 372{
367 struct quotause *qup; 373 struct quotause *qup;
368 struct quotahandle *qh; 374 struct quotahandle *qh;
369 const char *impl; 375 const char *impl;
370 unsigned restrictions; 376 unsigned restrictions;
 377 const char *idtypename;
371 378
372 qup = quotause_create(); 379 qup = quotause_create();
373 strcpy(qup->fsname, filesys); 380 strcpy(qup->fsname, filesys);
374 if (defaultq) 381 if (defaultq)
375 qup->flags |= DEFAULT; 382 qup->flags |= DEFAULT;
376 383
377 qh = quota_open(filesys); 384 qh = quota_open(filesys);
378 if (qh == NULL) { 385 if (qh == NULL) {
379 quotause_destroy(qup); 386 quotause_destroy(qup);
380 return NULL; 387 return NULL;
381 } 388 }
382 389
383 impl = quota_getimplname(qh); 390 impl = quota_getimplname(qh);
384 if (impl == NULL) { 391 if (impl == NULL) {
385 impl = "???"; 392 impl = "???";
386 } 393 }
387 strlcpy(qup->implementation, impl, sizeof(qup->implementation)); 394 strlcpy(qup->implementation, impl, sizeof(qup->implementation));
388 395
389 restrictions = quota_getrestrictions(qh); 396 restrictions = quota_getrestrictions(qh);
390 if ((restrictions & QUOTA_RESTRICT_UNIFORMGRACE) == 0) { 397 if ((restrictions & QUOTA_RESTRICT_UNIFORMGRACE) == 0) {
391 qup->flags |= XGRACE;  398 qup->flags |= XGRACE;
392 } 399 }
393 400
 401 if (*idtypename_p == NULL) {
 402 idtypename = quota_idtype_getname(qh, idtype);
 403 *idtypename_p = strdup(idtypename);
 404 if (*idtypename_p == NULL) {
 405 errx(1, "Out of memory");
 406 }
 407 }
 408
394 if (dogetprivs2(qh, idtype, id, defaultq, QUOTA_OBJTYPE_BLOCKS, qup)) { 409 if (dogetprivs2(qh, idtype, id, defaultq, QUOTA_OBJTYPE_BLOCKS, qup)) {
395 quota_close(qh); 410 quota_close(qh);
396 quotause_destroy(qup); 411 quotause_destroy(qup);
397 return NULL; 412 return NULL;
398 } 413 }
399 414
400 if (dogetprivs2(qh, idtype, id, defaultq, QUOTA_OBJTYPE_FILES, qup)) { 415 if (dogetprivs2(qh, idtype, id, defaultq, QUOTA_OBJTYPE_FILES, qup)) {
401 quota_close(qh); 416 quota_close(qh);
402 quotause_destroy(qup); 417 quotause_destroy(qup);
403 return NULL; 418 return NULL;
404 } 419 }
405 420
406 quota_close(qh); 421 quota_close(qh);
@@ -422,34 +437,34 @@ putprivs2(uint32_t id, int idtype, struc @@ -422,34 +437,34 @@ putprivs2(uint32_t id, int idtype, struc
422 } else { 437 } else {
423 snprintf(idname, sizeof(idname), "%s %u", 438 snprintf(idname, sizeof(idname), "%s %u",
424 idtype == QUOTA_IDTYPE_USER ? "uid" : "gid", id); 439 idtype == QUOTA_IDTYPE_USER ? "uid" : "gid", id);
425 } 440 }
426 441
427 qh = quota_open(qup->fsname); 442 qh = quota_open(qup->fsname);
428 if (qh == NULL) { 443 if (qh == NULL) {
429 err(1, "%s: quota_open", qup->fsname); 444 err(1, "%s: quota_open", qup->fsname);
430 } 445 }
431 446
432 qk.qk_idtype = idtype; 447 qk.qk_idtype = idtype;
433 qk.qk_id = id; 448 qk.qk_id = id;
434 qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS; 449 qk.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
435 if (quota_put(qh, &qk, &qup->qv[QL_BLK])) { 450 if (quota_put(qh, &qk, &qup->qv[QO_BLK])) {
436 err(1, "%s: quota_put (%s blocks)", qup->fsname, idname); 451 err(1, "%s: quota_put (%s blocks)", qup->fsname, idname);
437 } 452 }
438 453
439 qk.qk_idtype = idtype; 454 qk.qk_idtype = idtype;
440 qk.qk_id = id; 455 qk.qk_id = id;
441 qk.qk_objtype = QUOTA_OBJTYPE_FILES; 456 qk.qk_objtype = QUOTA_OBJTYPE_FILES;
442 if (quota_put(qh, &qk, &qup->qv[QL_FL])) { 457 if (quota_put(qh, &qk, &qup->qv[QO_FL])) {
443 err(1, "%s: quota_put (%s files)", qup->fsname, idname); 458 err(1, "%s: quota_put (%s files)", qup->fsname, idname);
444 } 459 }
445 460
446 quota_close(qh); 461 quota_close(qh);
447} 462}
448 463
449//////////////////////////////////////////////////////////// 464////////////////////////////////////////////////////////////
450// quota format switch 465// quota format switch
451 466
452/* 467/*
453 * Collect the requested quota information. 468 * Collect the requested quota information.
454 */ 469 */
455static struct quotalist * 470static struct quotalist *
@@ -463,27 +478,28 @@ getprivs(long id, int defaultq, int idty @@ -463,27 +478,28 @@ getprivs(long id, int defaultq, int idty
463 qlist = quotalist_create(); 478 qlist = quotalist_create();
464 479
465 nfst = getmntinfo(&fst, MNT_WAIT); 480 nfst = getmntinfo(&fst, MNT_WAIT);
466 if (nfst == 0) 481 if (nfst == 0)
467 errx(1, "no filesystems mounted!"); 482 errx(1, "no filesystems mounted!");
468 483
469 for (i = 0; i < nfst; i++) { 484 for (i = 0; i < nfst; i++) {
470 if ((fst[i].f_flag & ST_QUOTA) == 0) 485 if ((fst[i].f_flag & ST_QUOTA) == 0)
471 continue; 486 continue;
472 if (filesys && 487 if (filesys &&
473 strcmp(fst[i].f_mntonname, filesys) != 0 && 488 strcmp(fst[i].f_mntonname, filesys) != 0 &&
474 strcmp(fst[i].f_mntfromname, filesys) != 0) 489 strcmp(fst[i].f_mntfromname, filesys) != 0)
475 continue; 490 continue;
476 qup = getprivs2(id, idtype, fst[i].f_mntonname, defaultq); 491 qup = getprivs2(id, idtype, fst[i].f_mntonname, defaultq,
 492 &qlist->idtypename);
477 if (qup == NULL) { 493 if (qup == NULL) {
478 /* 494 /*
479 * XXX: returning NULL is totally wrong. On 495 * XXX: returning NULL is totally wrong. On
480 * serious error, abort; on minor error, warn 496 * serious error, abort; on minor error, warn
481 * and continue. 497 * and continue.
482 * 498 *
483 * Note: we cannot warn unconditionally here 499 * Note: we cannot warn unconditionally here
484 * because this case apparently includes "no 500 * because this case apparently includes "no
485 * quota entry on this volume" and that causes 501 * quota entry on this volume" and that causes
486 * the atf tests to fail. Bletch. 502 * the atf tests to fail. Bletch.
487 */ 503 */
488 /*return NULL;*/ 504 /*return NULL;*/
489 /*warnx("getprivs2 failed");*/ 505 /*warnx("getprivs2 failed");*/
@@ -669,83 +685,81 @@ top: @@ -669,83 +685,81 @@ top:
669 if (sigprocmask(SIG_SETMASK, &os, NULL) == -1) 685 if (sigprocmask(SIG_SETMASK, &os, NULL) == -1)
670 err(1, "sigprocmask"); 686 err(1, "sigprocmask");
671 if (!WIFEXITED(lst) || WEXITSTATUS(lst) != 0) 687 if (!WIFEXITED(lst) || WEXITSTATUS(lst) != 0)
672 return 0; 688 return 0;
673 return 1; 689 return 1;
674 } 690 }
675} 691}
676 692
677/* 693/*
678 * Convert a quotause list to an ASCII file. 694 * Convert a quotause list to an ASCII file.
679 */ 695 */
680static int 696static int
681writeprivs(struct quotalist *qlist, int outfd, const char *name, 697writeprivs(struct quotalist *qlist, int outfd, const char *name,
682 int idtype) 698 int idtype, const char *idtypename)
683{ 699{
684 struct quotause *qup; 700 struct quotause *qup;
685 FILE *fd; 701 FILE *fd;
686 char b0[32], b1[32], b2[32], b3[32]; 702 char b0[32], b1[32], b2[32], b3[32];
687 703
688 (void)ftruncate(outfd, 0); 704 (void)ftruncate(outfd, 0);
689 (void)lseek(outfd, (off_t)0, SEEK_SET); 705 (void)lseek(outfd, (off_t)0, SEEK_SET);
690 if ((fd = fdopen(dup(outfd), "w")) == NULL) 706 if ((fd = fdopen(dup(outfd), "w")) == NULL)
691 errx(1, "fdopen"); 707 errx(1, "fdopen");
692 if (name == NULL) { 708 if (name == NULL) {
693 fprintf(fd, "Default %s quotas:\n", 709 fprintf(fd, "Default %s quotas:\n", idtypename);
694 ufs_quota_class_names[idtype]); 
695 } else { 710 } else {
696 fprintf(fd, "Quotas for %s %s:\n", 711 fprintf(fd, "Quotas for %s %s:\n", idtypename, name);
697 ufs_quota_class_names[idtype], name); 
698 } 712 }
699 for (qup = qlist->head; qup; qup = qup->next) { 713 for (qup = qlist->head; qup; qup = qup->next) {
700 struct quotaval *q = qup->qv; 714 struct quotaval *q = qup->qv;
701 fprintf(fd, "%s (%s):\n", 715 fprintf(fd, "%s (%s):\n",
702 qup->fsname, qup->implementation); 716 qup->fsname, qup->implementation);
703 if ((qup->flags & DEFAULT) == 0 || (qup->flags & XGRACE) != 0) { 717 if ((qup->flags & DEFAULT) == 0 || (qup->flags & XGRACE) != 0) {
704 fprintf(fd, "\tblocks in use: %s, " 718 fprintf(fd, "\tblocks in use: %s, "
705 "limits (soft = %s, hard = %s", 719 "limits (soft = %s, hard = %s",
706 intprt(b1, 21, q[QL_BLK].qv_usage, 720 intprt(b1, 21, q[QO_BLK].qv_usage,
707 HN_NOSPACE | HN_B, Hflag),  721 HN_NOSPACE | HN_B, Hflag),
708 intprt(b2, 21, q[QL_BLK].qv_softlimit, 722 intprt(b2, 21, q[QO_BLK].qv_softlimit,
709 HN_NOSPACE | HN_B, Hflag), 723 HN_NOSPACE | HN_B, Hflag),
710 intprt(b3, 21, q[QL_BLK].qv_hardlimit, 724 intprt(b3, 21, q[QO_BLK].qv_hardlimit,
711 HN_NOSPACE | HN_B, Hflag)); 725 HN_NOSPACE | HN_B, Hflag));
712 if (qup->flags & XGRACE) 726 if (qup->flags & XGRACE)
713 fprintf(fd, ", "); 727 fprintf(fd, ", ");
714 } else 728 } else
715 fprintf(fd, "\tblocks: ("); 729 fprintf(fd, "\tblocks: (");
716  730
717 if (qup->flags & (XGRACE|DEFAULT)) { 731 if (qup->flags & (XGRACE|DEFAULT)) {
718 fprintf(fd, "grace = %s", 732 fprintf(fd, "grace = %s",
719 timepprt(b0, 21, q[QL_BLK].qv_grace, Hflag)); 733 timepprt(b0, 21, q[QO_BLK].qv_grace, Hflag));
720 } 734 }
721 fprintf(fd, ")\n"); 735 fprintf(fd, ")\n");
722 if ((qup->flags & DEFAULT) == 0 || (qup->flags & XGRACE) != 0) { 736 if ((qup->flags & DEFAULT) == 0 || (qup->flags & XGRACE) != 0) {
723 fprintf(fd, "\tinodes in use: %s, " 737 fprintf(fd, "\tinodes in use: %s, "
724 "limits (soft = %s, hard = %s", 738 "limits (soft = %s, hard = %s",
725 intprt(b1, 21, q[QL_FL].qv_usage, 739 intprt(b1, 21, q[QO_FL].qv_usage,
726 HN_NOSPACE, Hflag), 740 HN_NOSPACE, Hflag),
727 intprt(b2, 21, q[QL_FL].qv_softlimit, 741 intprt(b2, 21, q[QO_FL].qv_softlimit,
728 HN_NOSPACE, Hflag), 742 HN_NOSPACE, Hflag),
729 intprt(b3, 21, q[QL_FL].qv_hardlimit, 743 intprt(b3, 21, q[QO_FL].qv_hardlimit,
730 HN_NOSPACE, Hflag)); 744 HN_NOSPACE, Hflag));
731 if (qup->flags & XGRACE) 745 if (qup->flags & XGRACE)
732 fprintf(fd, ", "); 746 fprintf(fd, ", ");
733 } else 747 } else
734 fprintf(fd, "\tinodes: ("); 748 fprintf(fd, "\tinodes: (");
735 749
736 if (qup->flags & (XGRACE|DEFAULT)) { 750 if (qup->flags & (XGRACE|DEFAULT)) {
737 fprintf(fd, "grace = %s", 751 fprintf(fd, "grace = %s",
738 timepprt(b0, 21, q[QL_FL].qv_grace, Hflag)); 752 timepprt(b0, 21, q[QO_FL].qv_grace, Hflag));
739 } 753 }
740 fprintf(fd, ")\n"); 754 fprintf(fd, ")\n");
741 } 755 }
742 fclose(fd); 756 fclose(fd);
743 return 1; 757 return 1;
744} 758}
745 759
746/* 760/*
747 * Merge changes to an ASCII file into a quotause list. 761 * Merge changes to an ASCII file into a quotause list.
748 */ 762 */
749static int 763static int
750readprivs(struct quotalist *qlist, int infd, int dflag) 764readprivs(struct quotalist *qlist, int infd, int dflag)
751{ 765{
@@ -910,108 +924,108 @@ readprivs(struct quotalist *qlist, int i @@ -910,108 +924,108 @@ readprivs(struct quotalist *qlist, int i
910 if (cnt == 4) { 924 if (cnt == 4) {
911 if (timeprd(stime, &gracei) != 0) { 925 if (timeprd(stime, &gracei) != 0) {
912 warnx("%s:%s: bad number", fsp, stime); 926 warnx("%s:%s: bad number", fsp, stime);
913 goto out; 927 goto out;
914 } 928 }
915 } 929 }
916 } 930 }
917 for (qup = qlist->head; qup; qup = qup->next) { 931 for (qup = qlist->head; qup; qup = qup->next) {
918 struct quotaval *q = qup->qv; 932 struct quotaval *q = qup->qv;
919 char b1[32], b2[32]; 933 char b1[32], b2[32];
920 if (strcmp(fsp, qup->fsname)) 934 if (strcmp(fsp, qup->fsname))
921 continue; 935 continue;
922 if (version == 1 && dflag) { 936 if (version == 1 && dflag) {
923 q[QL_BLK].qv_grace = graceb; 937 q[QO_BLK].qv_grace = graceb;
924 q[QL_FL].qv_grace = gracei; 938 q[QO_FL].qv_grace = gracei;
925 qup->flags |= FOUND; 939 qup->flags |= FOUND;
926 continue; 940 continue;
927 } 941 }
928 942
929 if (strcmp(intprt(b1, 21, q[QL_BLK].qv_usage, 943 if (strcmp(intprt(b1, 21, q[QO_BLK].qv_usage,
930 HN_NOSPACE | HN_B, Hflag), 944 HN_NOSPACE | HN_B, Hflag),
931 scurb) != 0 || 945 scurb) != 0 ||
932 strcmp(intprt(b2, 21, q[QL_FL].qv_usage, 946 strcmp(intprt(b2, 21, q[QO_FL].qv_usage,
933 HN_NOSPACE, Hflag), 947 HN_NOSPACE, Hflag),
934 scuri) != 0) { 948 scuri) != 0) {
935 warnx("%s: cannot change current allocation", 949 warnx("%s: cannot change current allocation",
936 fsp); 950 fsp);
937 break; 951 break;
938 } 952 }
939 /* 953 /*
940 * Cause time limit to be reset when the quota 954 * Cause time limit to be reset when the quota
941 * is next used if previously had no soft limit 955 * is next used if previously had no soft limit
942 * or were under it, but now have a soft limit 956 * or were under it, but now have a soft limit
943 * and are over it. 957 * and are over it.
944 */ 958 */
945 if (q[QL_BLK].qv_usage && 959 if (q[QO_BLK].qv_usage &&
946 q[QL_BLK].qv_usage >= softb && 960 q[QO_BLK].qv_usage >= softb &&
947 (q[QL_BLK].qv_softlimit == 0 || 961 (q[QO_BLK].qv_softlimit == 0 ||
948 q[QL_BLK].qv_usage < q[QL_BLK].qv_softlimit)) 962 q[QO_BLK].qv_usage < q[QO_BLK].qv_softlimit))
949 q[QL_BLK].qv_expiretime = 0; 963 q[QO_BLK].qv_expiretime = 0;
950 if (q[QL_FL].qv_usage && 964 if (q[QO_FL].qv_usage &&
951 q[QL_FL].qv_usage >= softi && 965 q[QO_FL].qv_usage >= softi &&
952 (q[QL_FL].qv_softlimit == 0 || 966 (q[QO_FL].qv_softlimit == 0 ||
953 q[QL_FL].qv_usage < q[QL_FL].qv_softlimit)) 967 q[QO_FL].qv_usage < q[QO_FL].qv_softlimit))
954 q[QL_FL].qv_expiretime = 0; 968 q[QO_FL].qv_expiretime = 0;
955 q[QL_BLK].qv_softlimit = softb; 969 q[QO_BLK].qv_softlimit = softb;
956 q[QL_BLK].qv_hardlimit = hardb; 970 q[QO_BLK].qv_hardlimit = hardb;
957 if (version == 2) 971 if (version == 2)
958 q[QL_BLK].qv_grace = graceb; 972 q[QO_BLK].qv_grace = graceb;
959 q[QL_FL].qv_softlimit = softi; 973 q[QO_FL].qv_softlimit = softi;
960 q[QL_FL].qv_hardlimit = hardi; 974 q[QO_FL].qv_hardlimit = hardi;
961 if (version == 2) 975 if (version == 2)
962 q[QL_FL].qv_grace = gracei; 976 q[QO_FL].qv_grace = gracei;
963 qup->flags |= FOUND; 977 qup->flags |= FOUND;
964 } 978 }
965 } 979 }
966out: 980out:
967 fclose(fd); 981 fclose(fd);
968 /* 982 /*
969 * Disable quotas for any filesystems that have not been found. 983 * Disable quotas for any filesystems that have not been found.
970 */ 984 */
971 for (qup = qlist->head; qup; qup = qup->next) { 985 for (qup = qlist->head; qup; qup = qup->next) {
972 struct quotaval *q = qup->qv; 986 struct quotaval *q = qup->qv;
973 if (qup->flags & FOUND) { 987 if (qup->flags & FOUND) {
974 qup->flags &= ~FOUND; 988 qup->flags &= ~FOUND;
975 continue; 989 continue;
976 } 990 }
977 q[QL_BLK].qv_softlimit = UQUAD_MAX; 991 q[QO_BLK].qv_softlimit = UQUAD_MAX;
978 q[QL_BLK].qv_hardlimit = UQUAD_MAX; 992 q[QO_BLK].qv_hardlimit = UQUAD_MAX;
979 q[QL_BLK].qv_grace = 0; 993 q[QO_BLK].qv_grace = 0;
980 q[QL_FL].qv_softlimit = UQUAD_MAX; 994 q[QO_FL].qv_softlimit = UQUAD_MAX;
981 q[QL_FL].qv_hardlimit = UQUAD_MAX; 995 q[QO_FL].qv_hardlimit = UQUAD_MAX;
982 q[QL_FL].qv_grace = 0; 996 q[QO_FL].qv_grace = 0;
983 } 997 }
984 return 1; 998 return 1;
985} 999}
986 1000
987//////////////////////////////////////////////////////////// 1001////////////////////////////////////////////////////////////
988// actions 1002// actions
989 1003
990static void 1004static void
991replicate(const char *fs, int idtype, const char *protoname, 1005replicate(const char *fs, int idtype, const char *protoname,
992 char **names, int numnames) 1006 char **names, int numnames)
993{ 1007{
994 long protoid, id; 1008 long protoid, id;
995 struct quotalist *protoprivs; 1009 struct quotalist *protoprivs;
996 struct quotause *qup; 1010 struct quotause *qup;
997 int i; 1011 int i;
998 1012
999 if ((protoid = getidbyname(protoname, idtype)) == -1) 1013 if ((protoid = getidbyname(protoname, idtype)) == -1)
1000 exit(1); 1014 exit(1);
1001 protoprivs = getprivs(protoid, 0, idtype, fs); 1015 protoprivs = getprivs(protoid, 0, idtype, fs);
1002 for (qup = protoprivs->head; qup; qup = qup->next) { 1016 for (qup = protoprivs->head; qup; qup = qup->next) {
1003 qup->qv[QL_BLK].qv_expiretime = 0; 1017 qup->qv[QO_BLK].qv_expiretime = 0;
1004 qup->qv[QL_FL].qv_expiretime = 0; 1018 qup->qv[QO_FL].qv_expiretime = 0;
1005 } 1019 }
1006 for (i=0; i<numnames; i++) { 1020 for (i=0; i<numnames; i++) {
1007 id = getidbyname(names[i], idtype); 1021 id = getidbyname(names[i], idtype);
1008 if (id == -1) 1022 if (id == -1)
1009 continue; 1023 continue;
1010 putprivs(id, idtype, protoprivs); 1024 putprivs(id, idtype, protoprivs);
1011 } 1025 }
1012 /* XXX */ 1026 /* XXX */
1013 /* quotalist_destroy(protoprivs); */ 1027 /* quotalist_destroy(protoprivs); */
1014} 1028}
1015 1029
1016static void 1030static void
1017assign(const char *fs, int idtype, 1031assign(const char *fs, int idtype,
@@ -1063,47 +1077,47 @@ assign(const char *fs, int idtype, @@ -1063,47 +1077,47 @@ assign(const char *fs, int idtype,
1063 dflag = 1; 1077 dflag = 1;
1064 } else { 1078 } else {
1065 id = getidbyname(names[i], idtype); 1079 id = getidbyname(names[i], idtype);
1066 if (id == -1) 1080 if (id == -1)
1067 continue; 1081 continue;
1068 dflag = 0; 1082 dflag = 0;
1069 } 1083 }
1070 1084
1071 curprivs = getprivs(id, dflag, idtype, fs); 1085 curprivs = getprivs(id, dflag, idtype, fs);
1072 for (lqup = curprivs->head; lqup; lqup = lqup->next) { 1086 for (lqup = curprivs->head; lqup; lqup = lqup->next) {
1073 struct quotaval *q = lqup->qv; 1087 struct quotaval *q = lqup->qv;
1074 if (soft) { 1088 if (soft) {
1075 if (!dflag && softb && 1089 if (!dflag && softb &&
1076 q[QL_BLK].qv_usage >= softb && 1090 q[QO_BLK].qv_usage >= softb &&
1077 (q[QL_BLK].qv_softlimit == 0 || 1091 (q[QO_BLK].qv_softlimit == 0 ||
1078 q[QL_BLK].qv_usage < 1092 q[QO_BLK].qv_usage <
1079 q[QL_BLK].qv_softlimit)) 1093 q[QO_BLK].qv_softlimit))
1080 q[QL_BLK].qv_expiretime = 0; 1094 q[QO_BLK].qv_expiretime = 0;
1081 if (!dflag && softi && 1095 if (!dflag && softi &&
1082 q[QL_FL].qv_usage >= softb && 1096 q[QO_FL].qv_usage >= softb &&
1083 (q[QL_FL].qv_softlimit == 0 || 1097 (q[QO_FL].qv_softlimit == 0 ||
1084 q[QL_FL].qv_usage < 1098 q[QO_FL].qv_usage <
1085 q[QL_FL].qv_softlimit)) 1099 q[QO_FL].qv_softlimit))
1086 q[QL_FL].qv_expiretime = 0; 1100 q[QO_FL].qv_expiretime = 0;
1087 q[QL_BLK].qv_softlimit = softb; 1101 q[QO_BLK].qv_softlimit = softb;
1088 q[QL_FL].qv_softlimit = softi; 1102 q[QO_FL].qv_softlimit = softi;
1089 } 1103 }
1090 if (hard) { 1104 if (hard) {
1091 q[QL_BLK].qv_hardlimit = hardb; 1105 q[QO_BLK].qv_hardlimit = hardb;
1092 q[QL_FL].qv_hardlimit = hardi; 1106 q[QO_FL].qv_hardlimit = hardi;
1093 } 1107 }
1094 if (grace) { 1108 if (grace) {
1095 q[QL_BLK].qv_grace = graceb; 1109 q[QO_BLK].qv_grace = graceb;
1096 q[QL_FL].qv_grace = gracei; 1110 q[QO_FL].qv_grace = gracei;
1097 } 1111 }
1098 } 1112 }
1099 putprivs(id, idtype, curprivs); 1113 putprivs(id, idtype, curprivs);
1100 quotalist_destroy(curprivs); 1114 quotalist_destroy(curprivs);
1101 } 1115 }
1102} 1116}
1103 1117
1104static void 1118static void
1105clear(const char *fs, int idtype, char **names, int numnames) 1119clear(const char *fs, int idtype, char **names, int numnames)
1106{ 1120{
1107 clearpriv(numnames, names, fs, idtype); 1121 clearpriv(numnames, names, fs, idtype);
1108} 1122}
1109 1123
@@ -1116,27 +1130,28 @@ editone(const char *fs, int idtype, cons @@ -1116,27 +1130,28 @@ editone(const char *fs, int idtype, cons
1116 int dflag; 1130 int dflag;
1117 1131
1118 if (name == NULL) { 1132 if (name == NULL) {
1119 id = 0; 1133 id = 0;
1120 dflag = 1; 1134 dflag = 1;
1121 } else { 1135 } else {
1122 id = getidbyname(name, idtype); 1136 id = getidbyname(name, idtype);
1123 if (id == -1) 1137 if (id == -1)
1124 return; 1138 return;
1125 dflag = 0; 1139 dflag = 0;
1126 } 1140 }
1127 curprivs = getprivs(id, dflag, idtype, fs); 1141 curprivs = getprivs(id, dflag, idtype, fs);
1128 1142
1129 if (writeprivs(curprivs, tmpfd, name, idtype) == 0) 1143 if (writeprivs(curprivs, tmpfd, name, idtype,
 1144 curprivs->idtypename) == 0)
1130 goto fail; 1145 goto fail;
1131 1146
1132 if (editit(tmppath) == 0) 1147 if (editit(tmppath) == 0)
1133 goto fail; 1148 goto fail;
1134 1149
1135 if (readprivs(curprivs, tmpfd, dflag) == 0) 1150 if (readprivs(curprivs, tmpfd, dflag) == 0)
1136 goto fail; 1151 goto fail;
1137 1152
1138 putprivs(id, idtype, curprivs); 1153 putprivs(id, idtype, curprivs);
1139fail: 1154fail:
1140 quotalist_destroy(curprivs); 1155 quotalist_destroy(curprivs);
1141} 1156}
1142 1157