]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - quota/report.c
xfs_quota: push id/name printing down into report_mount()
[thirdparty/xfsprogs-dev.git] / quota / report.c
CommitLineData
5aead01d 1/*
da23017d
NS
2 * Copyright (c) 2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
5aead01d 4 *
da23017d
NS
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
5aead01d
NS
7 * published by the Free Software Foundation.
8 *
da23017d
NS
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
5aead01d 13 *
da23017d
NS
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
5aead01d
NS
17 */
18
6b803e5a 19#include "command.h"
904e8060 20#include <sys/types.h>
5aead01d
NS
21#include <pwd.h>
22#include <grp.h>
ce8d0b3a 23#include <utmp.h>
5aead01d
NS
24#include "init.h"
25#include "quota.h"
26
27static cmdinfo_t dump_cmd;
28static cmdinfo_t report_cmd;
29
30static void
31dump_help(void)
32{
33 dump_cmd.args = _("[-gpu] [-f file]");
34 dump_cmd.oneline = _("dump quota information for backup utilities");
35 printf(_(
36"\n"
37" create a backup file which contains quota limits information\n"
38" -g -- dump out group quota limits\n"
39" -p -- dump out project quota limits\n"
40" -u -- dump out user quota limits (default)\n"
41" -f -- write the dump out to the specified file\n"
42"\n"));
43}
44
45static void
46report_help(void)
47{
bb76b4b3 48 report_cmd.args = _("[-bir] [-gpu] [-ahntLNU] [-f file]");
5aead01d
NS
49 report_cmd.oneline = _("report filesystem quota information");
50 printf(_(
51"\n"
52" report used space and inodes, and quota limits, for a filesystem\n"
53" Example:\n"
54" 'report -igh'\n"
55" (reports inode usage for all groups, in an easy-to-read format)\n"
56" This command is the equivalent of the traditional repquota command, which\n"
57" prints a summary of the disk usage and quotas for the current filesystem,\n"
58" or all filesystems.\n"
59" -a -- report for all mounted filesystems with quota enabled\n"
60" -h -- report in a human-readable format\n"
1774874a
NS
61" -n -- skip identifier-to-name translations, just report IDs\n"
62" -N -- suppress the header from the output\n"
5aead01d 63" -t -- terse output format, hides rows which are all zero\n"
bb76b4b3 64" -L -- lower ID bound to report on\n"
ff1f79a7 65" -U -- upper ID bound to report on\n"
5aead01d
NS
66" -g -- report group usage and quota information\n"
67" -p -- report project usage and quota information\n"
68" -u -- report user usage and quota information\n"
69" -b -- report blocks-used information only\n"
70" -i -- report inodes-used information only\n"
71" -r -- report realtime-blocks-used information only\n"
72"\n"));
73}
74
75static void
76dump_file(
77 FILE *fp,
78 uint id,
79 uint type,
80 char *dev)
81{
82 fs_disk_quota_t d;
83
ec4cd312 84 if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) {
e127d47b 85 if (errno != ENOENT && errno != ENOSYS && errno != ESRCH)
ec4cd312 86 perror("XFS_GETQUOTA");
5aead01d 87 return;
ec4cd312 88 }
1774874a
NS
89 if (!d.d_blk_softlimit && !d.d_blk_hardlimit &&
90 !d.d_ino_softlimit && !d.d_ino_hardlimit &&
91 !d.d_rtb_softlimit && !d.d_rtb_hardlimit)
92 return;
5aead01d 93 fprintf(fp, "fs = %s\n", dev);
1774874a
NS
94 /* this branch is for backward compatibility reasons */
95 if (d.d_rtb_softlimit || d.d_rtb_hardlimit)
96 fprintf(fp, "%-10d %7llu %7llu %7llu %7llu %7llu %7llu\n", id,
97 (unsigned long long)d.d_blk_softlimit,
98 (unsigned long long)d.d_blk_hardlimit,
99 (unsigned long long)d.d_ino_softlimit,
100 (unsigned long long)d.d_ino_hardlimit,
101 (unsigned long long)d.d_rtb_softlimit,
102 (unsigned long long)d.d_rtb_hardlimit);
103 else
104 fprintf(fp, "%-10d %7llu %7llu %7llu %7llu\n", id,
105 (unsigned long long)d.d_blk_softlimit,
106 (unsigned long long)d.d_blk_hardlimit,
107 (unsigned long long)d.d_ino_softlimit,
108 (unsigned long long)d.d_ino_hardlimit);
5aead01d
NS
109}
110
111static void
112dump_limits_any_type(
113 FILE *fp,
114 uint type,
1774874a
NS
115 char *dir,
116 uint lower,
117 uint upper)
5aead01d
NS
118{
119 fs_path_t *mount;
1774874a 120 uint id;
5aead01d
NS
121
122 if ((mount = fs_table_lookup(dir, FS_MOUNT_POINT)) == NULL) {
e3210fd8 123 exitcode = 1;
5aead01d
NS
124 fprintf(stderr, "%s: cannot find mount point %s\n",
125 progname, dir);
126 return;
127 }
128
1774874a 129 if (upper) {
57cc6e78 130 for (id = lower; id <= upper; id++)
1774874a
NS
131 dump_file(fp, id, type, mount->fs_name);
132 return;
133 }
134
5aead01d
NS
135 switch (type) {
136 case XFS_GROUP_QUOTA: {
137 struct group *g;
138 setgrent();
139 while ((g = getgrent()) != NULL)
140 dump_file(fp, g->gr_gid, type, mount->fs_name);
141 endgrent();
142 break;
143 }
144 case XFS_PROJ_QUOTA: {
145 struct fs_project *p;
146 setprent();
147 while ((p = getprent()) != NULL)
148 dump_file(fp, p->pr_prid, type, mount->fs_name);
149 endprent();
150 break;
151 }
152 case XFS_USER_QUOTA: {
153 struct passwd *u;
154 setpwent();
155 while ((u = getpwent()) != NULL)
156 dump_file(fp, u->pw_uid, type, mount->fs_name);
157 endpwent();
158 break;
159 }
160 }
161}
162
163static int
164dump_f(
165 int argc,
166 char **argv)
167{
168 FILE *fp;
169 char *fname = NULL;
1774874a 170 uint lower = 0, upper = 0;
5aead01d
NS
171 int c, type = XFS_USER_QUOTA;
172
1774874a 173 while ((c = getopt(argc, argv, "f:gpuL:U:")) != EOF) {
5aead01d
NS
174 switch(c) {
175 case 'f':
176 fname = optarg;
177 break;
178 case 'g':
179 type = XFS_GROUP_QUOTA;
180 break;
181 case 'p':
182 type = XFS_PROJ_QUOTA;
183 break;
184 case 'u':
185 type = XFS_USER_QUOTA;
186 break;
1774874a
NS
187 case 'L':
188 lower = (uint)atoi(optarg);
189 break;
190 case 'U':
191 upper = (uint)atoi(optarg);
192 break;
5aead01d
NS
193 default:
194 return command_usage(&dump_cmd);
195 }
196 }
197
198 if (argc != optind)
199 return command_usage(&dump_cmd);
200
201 if ((fp = fopen_write_secure(fname)) == NULL)
202 return 0;
203
1774874a 204 dump_limits_any_type(fp, type, fs_path->fs_dir, lower, upper);
5aead01d
NS
205
206 if (fname)
207 fclose(fp);
208
209 return 0;
210}
211
212static void
213report_header(
214 FILE *fp,
215 uint form,
216 uint type,
217 fs_path_t *mount,
218 int flags)
219{
220 char *typename = type_to_string(type);
221 char scratch[64];
222 uint i, count;
223
224 if (flags & NO_HEADER_FLAG)
225 return;
226
227 /* line 1 */
228 fprintf(fp, _("%s quota on %s (%s)\n"),
229 typename, mount->fs_dir, mount->fs_name);
230
231 /* line 2 */
232 for (i = 0; i < 10; i++)
233 fputc(' ', fp);
234 if (form & XFS_BLOCK_QUOTA)
235 fprintf(fp, (flags & HUMAN_FLAG) ?
236 "%13c %s %13c" : "%20c %s %20c",
237 ' ', form_to_string(XFS_BLOCK_QUOTA), ' ');
238 if (form & XFS_INODE_QUOTA)
239 fprintf(fp, (flags & HUMAN_FLAG) ?
240 "%13c %s %13c" : "%20c %s %20c",
241 ' ', form_to_string(XFS_INODE_QUOTA), ' ');
242 if (form & XFS_RTBLOCK_QUOTA)
243 fprintf(fp, (flags & HUMAN_FLAG) ?
244 "%9c %s %9c" : "%15c %s %15c",
245 ' ', form_to_string(XFS_RTBLOCK_QUOTA), ' ');
246 fputc('\n', fp);
247
248 /* line 3 */
249 snprintf(scratch, sizeof(scratch), "%s ID", typename);
250 fprintf(fp, "%-10s ", scratch);
251 if (form & XFS_BLOCK_QUOTA)
252 fprintf(fp, (flags & HUMAN_FLAG) ?
253 _(" Used Soft Hard Warn/Grace ") :
254 _(" Used Soft Hard Warn/Grace "));
255 if (form & XFS_INODE_QUOTA)
256 fprintf(fp, (flags & HUMAN_FLAG) ?
257 _(" Used Soft Hard Warn/Grace ") :
258 _(" Used Soft Hard Warn/ Grace "));
259 if (form & XFS_RTBLOCK_QUOTA)
260 fprintf(fp, (flags & HUMAN_FLAG) ?
261 _(" Used Soft Hard Warn/Grace ") :
262 _(" Used Soft Hard Warn/Grace "));
263 fputc('\n', fp);
264
265 /* line 4 */
266 for (i = 0; i < 10; i++)
267 fputc('-', fp);
268 fputc(' ', fp);
269 count = (flags & HUMAN_FLAG) ? 33 : 50;
270 if (form & XFS_BLOCK_QUOTA) {
271 for (i = 0; i < count; i++)
272 fputc('-', fp);
273 fputc(' ', fp);
274 }
275 if (form & XFS_INODE_QUOTA) {
276 for (i = 0; i < count; i++)
277 fputc('-', fp);
278 fputc(' ', fp);
279 }
280 if (form & XFS_RTBLOCK_QUOTA) {
281 for (i = 0; i < count; i++)
282 fputc('-', fp);
283 fputc(' ', fp);
284 }
285 fputc('\n', fp);
286}
287
288static int
289report_mount(
290 FILE *fp,
291 __uint32_t id,
292 char *name,
293 uint form,
294 uint type,
295 fs_path_t *mount,
296 uint flags)
297{
298 fs_disk_quota_t d;
299 char *dev = mount->fs_name;
300 char c[8], h[8], s[8];
301 uint qflags;
302 int count;
303
ec4cd312 304 if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) {
e127d47b 305 if (errno != ENOENT && errno != ENOSYS && errno != ESRCH)
ec4cd312 306 perror("XFS_GETQUOTA");
5aead01d 307 return 0;
ec4cd312 308 }
5aead01d
NS
309
310 if (flags & TERSE_FLAG) {
311 count = 0;
312 if ((form & XFS_BLOCK_QUOTA) && d.d_bcount)
313 count++;
314 if ((form & XFS_INODE_QUOTA) && d.d_icount)
315 count++;
316 if ((form & XFS_RTBLOCK_QUOTA) && d.d_rtbcount)
317 count++;
318 if (!count)
319 return 0;
320 }
321
322 if (!(flags & NO_HEADER_FLAG))
323 report_header(fp, form, type, mount, flags);
324
a265445e
ES
325 if ((name == NULL) || (flags & NO_LOOKUP_FLAG))
326 fprintf(fp, "#%-10u", id);
327 else
328 fprintf(fp, "%-10s", name);
329
5aead01d
NS
330 if (form & XFS_BLOCK_QUOTA) {
331 qflags = (flags & HUMAN_FLAG);
332 if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
333 qflags |= LIMIT_FLAG;
334 if (d.d_blk_softlimit && d.d_bcount > d.d_blk_softlimit)
335 qflags |= QUOTA_FLAG;
336 if (flags & HUMAN_FLAG)
337 fprintf(fp, " %6s %6s %6s %02d %8s",
338 bbs_to_string(d.d_bcount, c, sizeof(c)),
339 bbs_to_string(d.d_blk_softlimit, s, sizeof(s)),
340 bbs_to_string(d.d_blk_hardlimit, h, sizeof(h)),
341 d.d_bwarns,
342 time_to_string(d.d_btimer, qflags));
343 else
344 fprintf(fp, " %10llu %10llu %10llu %02d %9s",
345 (unsigned long long)d.d_bcount >> 1,
346 (unsigned long long)d.d_blk_softlimit >> 1,
347 (unsigned long long)d.d_blk_hardlimit >> 1,
348 d.d_bwarns,
349 time_to_string(d.d_btimer, qflags));
350 }
351 if (form & XFS_INODE_QUOTA) {
352 qflags = (flags & HUMAN_FLAG);
353 if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
354 qflags |= LIMIT_FLAG;
355 if (d.d_ino_softlimit && d.d_icount > d.d_ino_softlimit)
356 qflags |= QUOTA_FLAG;
357 if (flags & HUMAN_FLAG)
358 fprintf(fp, " %6s %6s %6s %02d %8s",
359 num_to_string(d.d_icount, c, sizeof(c)),
360 num_to_string(d.d_ino_softlimit, s, sizeof(s)),
361 num_to_string(d.d_ino_hardlimit, h, sizeof(h)),
362 d.d_iwarns,
363 time_to_string(d.d_itimer, qflags));
364 else
365 fprintf(fp, " %10llu %10llu %10llu %02d %9s",
366 (unsigned long long)d.d_icount,
367 (unsigned long long)d.d_ino_softlimit,
368 (unsigned long long)d.d_ino_hardlimit,
369 d.d_iwarns,
370 time_to_string(d.d_itimer, qflags));
371 }
372 if (form & XFS_RTBLOCK_QUOTA) {
373 qflags = (flags & HUMAN_FLAG);
374 if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
375 qflags |= LIMIT_FLAG;
376 if (d.d_rtb_softlimit && d.d_rtbcount > d.d_rtb_softlimit)
377 qflags |= QUOTA_FLAG;
378 if (flags & HUMAN_FLAG)
379 fprintf(fp, " %6s %6s %6s %02d %8s",
380 bbs_to_string(d.d_rtbcount, c, sizeof(c)),
381 bbs_to_string(d.d_rtb_softlimit, s, sizeof(s)),
382 bbs_to_string(d.d_rtb_hardlimit, h, sizeof(h)),
383 d.d_rtbwarns,
384 time_to_string(d.d_rtbtimer, qflags));
385 else
386 fprintf(fp, " %10llu %10llu %10llu %02d %9s",
387 (unsigned long long)d.d_rtbcount >> 1,
388 (unsigned long long)d.d_rtb_softlimit >> 1,
389 (unsigned long long)d.d_rtb_hardlimit >> 1,
390 d.d_rtbwarns,
391 time_to_string(d.d_rtbtimer, qflags));
392 }
393 fputc('\n', fp);
394 return 1;
395}
396
397static void
398report_user_mount(
399 FILE *fp,
400 uint form,
401 fs_path_t *mount,
1774874a
NS
402 uint lower,
403 uint upper,
5aead01d
NS
404 uint flags)
405{
1774874a 406 struct passwd *u;
1774874a
NS
407 uint id;
408
409 if (upper) { /* identifier range specified */
57cc6e78 410 for (id = lower; id <= upper; id++) {
a265445e 411 if (report_mount(fp, id, NULL,
1774874a
NS
412 form, XFS_USER_QUOTA, mount, flags))
413 flags |= NO_HEADER_FLAG;
414 }
415 } else {
416 setpwent();
417 while ((u = getpwent()) != NULL) {
a265445e 418 if (report_mount(fp, u->pw_uid, u->pw_name,
1774874a
NS
419 form, XFS_USER_QUOTA, mount, flags))
420 flags |= NO_HEADER_FLAG;
421 }
422 endpwent();
423 }
5aead01d 424
5aead01d
NS
425 if (flags & NO_HEADER_FLAG)
426 fputc('\n', fp);
5aead01d
NS
427}
428
429static void
430report_group_mount(
431 FILE *fp,
432 uint form,
433 fs_path_t *mount,
1774874a
NS
434 uint lower,
435 uint upper,
5aead01d
NS
436 uint flags)
437{
1774874a 438 struct group *g;
1774874a
NS
439 uint id;
440
441 if (upper) { /* identifier range specified */
57cc6e78 442 for (id = lower; id <= upper; id++) {
a265445e 443 if (report_mount(fp, id, NULL,
1774874a
NS
444 form, XFS_GROUP_QUOTA, mount, flags))
445 flags |= NO_HEADER_FLAG;
446 }
447 } else {
448 setgrent();
449 while ((g = getgrent()) != NULL) {
a265445e 450 if (report_mount(fp, g->gr_gid, g->gr_name,
1774874a
NS
451 form, XFS_GROUP_QUOTA, mount, flags))
452 flags |= NO_HEADER_FLAG;
453 }
454 }
5aead01d
NS
455 if (flags & NO_HEADER_FLAG)
456 fputc('\n', fp);
457 endgrent();
458}
459
460static void
461report_project_mount(
462 FILE *fp,
463 uint form,
464 fs_path_t *mount,
1774874a
NS
465 uint lower,
466 uint upper,
5aead01d
NS
467 uint flags)
468{
469 fs_project_t *p;
1774874a
NS
470 uint id;
471
472 if (upper) { /* identifier range specified */
57cc6e78 473 for (id = lower; id <= upper; id++) {
a265445e 474 if (report_mount(fp, id, NULL,
1774874a
NS
475 form, XFS_PROJ_QUOTA, mount, flags))
476 flags |= NO_HEADER_FLAG;
477 }
478 } else {
479 setprent();
480 while ((p = getprent()) != NULL) {
a265445e 481 if (report_mount(fp, p->pr_prid, p->pr_name,
1774874a
NS
482 form, XFS_PROJ_QUOTA, mount, flags))
483 flags |= NO_HEADER_FLAG;
484 }
485 endprent();
486 }
5aead01d 487
5aead01d
NS
488 if (flags & NO_HEADER_FLAG)
489 fputc('\n', fp);
5aead01d
NS
490}
491
492static void
493report_any_type(
494 FILE *fp,
495 uint form,
496 uint type,
497 char *dir,
1774874a
NS
498 uint lower,
499 uint upper,
5aead01d
NS
500 uint flags)
501{
502 fs_cursor_t cursor;
503 fs_path_t *mount;
504
505 if (type & XFS_USER_QUOTA) {
506 fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
546bedf4 507 while ((mount = fs_cursor_next_entry(&cursor))) {
ec4cd312
AM
508 if (xfsquotactl(XFS_QSYNC, mount->fs_name,
509 XFS_USER_QUOTA, 0, NULL) < 0
510 && errno != ENOENT && errno != ENOSYS)
511 perror("XFS_QSYNC user quota");
1774874a
NS
512 report_user_mount(fp, form, mount,
513 lower, upper, flags);
546bedf4 514 }
5aead01d
NS
515 }
516 if (type & XFS_GROUP_QUOTA) {
517 fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
546bedf4 518 while ((mount = fs_cursor_next_entry(&cursor))) {
ec4cd312
AM
519 if (xfsquotactl(XFS_QSYNC, mount->fs_name,
520 XFS_GROUP_QUOTA, 0, NULL) < 0
521 && errno != ENOENT && errno != ENOSYS)
522 perror("XFS_QSYNC group quota");
1774874a
NS
523 report_group_mount(fp, form, mount,
524 lower, upper, flags);
546bedf4 525 }
5aead01d
NS
526 }
527 if (type & XFS_PROJ_QUOTA) {
528 fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
546bedf4 529 while ((mount = fs_cursor_next_entry(&cursor))) {
ec4cd312
AM
530 if (xfsquotactl(XFS_QSYNC, mount->fs_name,
531 XFS_PROJ_QUOTA, 0, NULL) < 0
532 && errno != ENOENT && errno != ENOSYS)
533 perror("XFS_QSYNC proj quota");
1774874a
NS
534 report_project_mount(fp, form, mount,
535 lower, upper, flags);
546bedf4 536 }
5aead01d
NS
537 }
538}
539
540static int
541report_f(
542 int argc,
543 char **argv)
544{
545 FILE *fp = NULL;
fa13a00f 546 char *fname = NULL;
1774874a 547 uint lower = 0, upper = 0;
5aead01d
NS
548 int c, flags = 0, type = 0, form = 0;
549
1774874a 550 while ((c = getopt(argc, argv, "abf:ghiL:NnprtuU:")) != EOF) {
5aead01d
NS
551 switch (c) {
552 case 'f':
553 fname = optarg;
554 break;
555 case 'b':
556 form |= XFS_BLOCK_QUOTA;
557 break;
558 case 'i':
559 form |= XFS_INODE_QUOTA;
560 break;
561 case 'r':
562 form |= XFS_RTBLOCK_QUOTA;
563 break;
564 case 'g':
565 type |= XFS_GROUP_QUOTA;
566 break;
567 case 'p':
568 type |= XFS_PROJ_QUOTA;
569 break;
570 case 'u':
571 type |= XFS_USER_QUOTA;
572 break;
573 case 'a':
574 flags |= ALL_MOUNTS_FLAG;
575 break;
576 case 'h':
577 flags |= HUMAN_FLAG;
578 break;
579 case 'n':
1774874a
NS
580 flags |= NO_LOOKUP_FLAG;
581 break;
582 case 'N':
5aead01d
NS
583 flags |= NO_HEADER_FLAG;
584 break;
585 case 't':
586 flags |= TERSE_FLAG;
587 break;
1774874a
NS
588 case 'L':
589 lower = (uint)atoi(optarg);
590 break;
591 case 'U':
592 upper = (uint)atoi(optarg);
593 break;
5aead01d
NS
594 default:
595 return command_usage(&report_cmd);
596 }
597 }
598
599 if (!form)
600 form = XFS_BLOCK_QUOTA;
601
602 if (!type)
603 type = XFS_USER_QUOTA | XFS_GROUP_QUOTA | XFS_PROJ_QUOTA;
604
605 if ((fp = fopen_write_secure(fname)) == NULL)
606 return 0;
607
fa13a00f
NS
608 if (argc == optind) {
609 if (flags & ALL_MOUNTS_FLAG)
610 report_any_type(fp, form, type, NULL,
611 lower, upper, flags);
a14d4093 612 else if (fs_path && (fs_path->fs_flags & FS_MOUNT_POINT))
fa13a00f
NS
613 report_any_type(fp, form, type, fs_path->fs_dir,
614 lower, upper, flags);
615 } else while (argc > optind) {
616 report_any_type(fp, form, type, argv[optind++],
617 lower, upper, flags);
1774874a 618 }
5aead01d
NS
619
620 if (fname)
621 fclose(fp);
622 return 0;
623}
624
625void
626report_init(void)
627{
ad765595 628 dump_cmd.name = "dump";
5aead01d
NS
629 dump_cmd.cfunc = dump_f;
630 dump_cmd.argmin = 0;
631 dump_cmd.argmax = -1;
632 dump_cmd.args = _("[-gpu] [-f file]");
633 dump_cmd.oneline = _("dump quota information for backup utilities");
634 dump_cmd.help = dump_help;
635
ad765595
AM
636 report_cmd.name = "report";
637 report_cmd.altname = "repquota";
5aead01d
NS
638 report_cmd.cfunc = report_f;
639 report_cmd.argmin = 0;
640 report_cmd.argmax = -1;
19473a2a 641 report_cmd.flags = CMD_FLAG_GLOBAL;
5aead01d
NS
642 report_cmd.args = _("[-bir] [-gpu] [-ahnt] [-f file]");
643 report_cmd.oneline = _("report filesystem quota information");
644 report_cmd.help = report_help;
645
646 if (expert) {
647 add_command(&dump_cmd);
648 add_command(&report_cmd);
649 }
650}