| @@ -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 |
42 | static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95"; | | 42 | static 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 |
84 | static const char *quotagroup = QUOTAGROUP; | | 86 | static 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 | |
94 | struct quotause { | | 96 | struct 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 | |
103 | struct quotalist { | | 105 | struct quotalist { |
104 | struct quotause *head; | | 106 | struct quotause *head; |
105 | struct quotause *tail; | | 107 | struct quotause *tail; |
| | | 108 | char *idtypename; |
106 | }; | | 109 | }; |
107 | | | 110 | |
108 | static void usage(void) __dead; | | 111 | static void usage(void) __dead; |
109 | | | 112 | |
110 | static int Hflag = 0; | | 113 | static 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 | */ |
124 | static int | | 127 | static int |
125 | getidbyname(const char *name, int idtype) | | 128 | getidbyname(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 | */ |
192 | static struct quotalist * | | 195 | static struct quotalist * |
193 | quotalist_create(void) | | 196 | quotalist_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 | */ |
211 | static void | | 215 | static void |
212 | quotalist_destroy(struct quotalist *qlist) | | 216 | quotalist_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 |
224 | static bool | | 229 | static bool |
225 | quotalist_empty(struct quotalist *qlist) | | 230 | quotalist_empty(struct quotalist *qlist) |
226 | { | | 231 | { |
227 | return qlist->head == NULL; | | 232 | return qlist->head == NULL; |
228 | } | | 233 | } |
229 | #endif | | 234 | #endif |
230 | | | 235 | |
231 | static void | | 236 | static void |
232 | quotalist_append(struct quotalist *qlist, struct quotause *qup) | | 237 | quotalist_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 | |
364 | static struct quotause * | | 369 | static struct quotause * |
365 | getprivs2(long id, int idtype, const char *filesys, int defaultq) | | 370 | getprivs2(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 | */ |
455 | static struct quotalist * | | 470 | static 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 | */ |
680 | static int | | 696 | static int |
681 | writeprivs(struct quotalist *qlist, int outfd, const char *name, | | 697 | writeprivs(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 | */ |
749 | static int | | 763 | static int |
750 | readprivs(struct quotalist *qlist, int infd, int dflag) | | 764 | readprivs(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 | } |
966 | out: | | 980 | out: |
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 | |
990 | static void | | 1004 | static void |
991 | replicate(const char *fs, int idtype, const char *protoname, | | 1005 | replicate(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 | |
1016 | static void | | 1030 | static void |
1017 | assign(const char *fs, int idtype, | | 1031 | assign(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 | |
1104 | static void | | 1118 | static void |
1105 | clear(const char *fs, int idtype, char **names, int numnames) | | 1119 | clear(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); |
1139 | fail: | | 1154 | fail: |
1140 | quotalist_destroy(curprivs); | | 1155 | quotalist_destroy(curprivs); |
1141 | } | | 1156 | } |
1142 | | | 1157 | |