]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - quota/report.c
xfs_quota: define Q_XGETNEXTQUOTA
[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{
85dcd9a0 48 report_cmd.args = _("[-bir] [-gpu] [-ahntlLNU] [-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"
85dcd9a0 66" -l -- look up names for IDs in lower-upper range\n"
5aead01d
NS
67" -g -- report group usage and quota information\n"
68" -p -- report project usage and quota information\n"
69" -u -- report user usage and quota information\n"
70" -b -- report blocks-used information only\n"
71" -i -- report inodes-used information only\n"
72" -r -- report realtime-blocks-used information only\n"
73"\n"));
74}
75
76static void
77dump_file(
78 FILE *fp,
79 uint id,
80 uint type,
81 char *dev)
82{
83 fs_disk_quota_t d;
84
ec4cd312 85 if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) {
e127d47b 86 if (errno != ENOENT && errno != ENOSYS && errno != ESRCH)
ec4cd312 87 perror("XFS_GETQUOTA");
5aead01d 88 return;
ec4cd312 89 }
1774874a
NS
90 if (!d.d_blk_softlimit && !d.d_blk_hardlimit &&
91 !d.d_ino_softlimit && !d.d_ino_hardlimit &&
92 !d.d_rtb_softlimit && !d.d_rtb_hardlimit)
93 return;
5aead01d 94 fprintf(fp, "fs = %s\n", dev);
1774874a
NS
95 /* this branch is for backward compatibility reasons */
96 if (d.d_rtb_softlimit || d.d_rtb_hardlimit)
97 fprintf(fp, "%-10d %7llu %7llu %7llu %7llu %7llu %7llu\n", id,
98 (unsigned long long)d.d_blk_softlimit,
99 (unsigned long long)d.d_blk_hardlimit,
100 (unsigned long long)d.d_ino_softlimit,
101 (unsigned long long)d.d_ino_hardlimit,
102 (unsigned long long)d.d_rtb_softlimit,
103 (unsigned long long)d.d_rtb_hardlimit);
104 else
105 fprintf(fp, "%-10d %7llu %7llu %7llu %7llu\n", id,
106 (unsigned long long)d.d_blk_softlimit,
107 (unsigned long long)d.d_blk_hardlimit,
108 (unsigned long long)d.d_ino_softlimit,
109 (unsigned long long)d.d_ino_hardlimit);
5aead01d
NS
110}
111
112static void
113dump_limits_any_type(
114 FILE *fp,
115 uint type,
1774874a
NS
116 char *dir,
117 uint lower,
118 uint upper)
5aead01d
NS
119{
120 fs_path_t *mount;
1774874a 121 uint id;
5aead01d
NS
122
123 if ((mount = fs_table_lookup(dir, FS_MOUNT_POINT)) == NULL) {
e3210fd8 124 exitcode = 1;
5aead01d
NS
125 fprintf(stderr, "%s: cannot find mount point %s\n",
126 progname, dir);
127 return;
128 }
129
1774874a 130 if (upper) {
57cc6e78 131 for (id = lower; id <= upper; id++)
1774874a
NS
132 dump_file(fp, id, type, mount->fs_name);
133 return;
134 }
135
5aead01d
NS
136 switch (type) {
137 case XFS_GROUP_QUOTA: {
138 struct group *g;
139 setgrent();
140 while ((g = getgrent()) != NULL)
141 dump_file(fp, g->gr_gid, type, mount->fs_name);
142 endgrent();
143 break;
144 }
145 case XFS_PROJ_QUOTA: {
146 struct fs_project *p;
147 setprent();
148 while ((p = getprent()) != NULL)
149 dump_file(fp, p->pr_prid, type, mount->fs_name);
150 endprent();
151 break;
152 }
153 case XFS_USER_QUOTA: {
154 struct passwd *u;
155 setpwent();
156 while ((u = getpwent()) != NULL)
157 dump_file(fp, u->pw_uid, type, mount->fs_name);
158 endpwent();
159 break;
160 }
161 }
162}
163
164static int
165dump_f(
166 int argc,
167 char **argv)
168{
169 FILE *fp;
170 char *fname = NULL;
1774874a 171 uint lower = 0, upper = 0;
5aead01d
NS
172 int c, type = XFS_USER_QUOTA;
173
1774874a 174 while ((c = getopt(argc, argv, "f:gpuL:U:")) != EOF) {
5aead01d
NS
175 switch(c) {
176 case 'f':
177 fname = optarg;
178 break;
179 case 'g':
180 type = XFS_GROUP_QUOTA;
181 break;
182 case 'p':
183 type = XFS_PROJ_QUOTA;
184 break;
185 case 'u':
186 type = XFS_USER_QUOTA;
187 break;
1774874a
NS
188 case 'L':
189 lower = (uint)atoi(optarg);
190 break;
191 case 'U':
192 upper = (uint)atoi(optarg);
193 break;
5aead01d
NS
194 default:
195 return command_usage(&dump_cmd);
196 }
197 }
198
199 if (argc != optind)
200 return command_usage(&dump_cmd);
201
202 if ((fp = fopen_write_secure(fname)) == NULL)
203 return 0;
204
1774874a 205 dump_limits_any_type(fp, type, fs_path->fs_dir, lower, upper);
5aead01d
NS
206
207 if (fname)
208 fclose(fp);
209
210 return 0;
211}
212
213static void
214report_header(
215 FILE *fp,
216 uint form,
217 uint type,
218 fs_path_t *mount,
219 int flags)
220{
221 char *typename = type_to_string(type);
222 char scratch[64];
223 uint i, count;
224
225 if (flags & NO_HEADER_FLAG)
226 return;
227
228 /* line 1 */
229 fprintf(fp, _("%s quota on %s (%s)\n"),
230 typename, mount->fs_dir, mount->fs_name);
231
232 /* line 2 */
233 for (i = 0; i < 10; i++)
234 fputc(' ', fp);
235 if (form & XFS_BLOCK_QUOTA)
236 fprintf(fp, (flags & HUMAN_FLAG) ?
237 "%13c %s %13c" : "%20c %s %20c",
238 ' ', form_to_string(XFS_BLOCK_QUOTA), ' ');
239 if (form & XFS_INODE_QUOTA)
240 fprintf(fp, (flags & HUMAN_FLAG) ?
241 "%13c %s %13c" : "%20c %s %20c",
242 ' ', form_to_string(XFS_INODE_QUOTA), ' ');
243 if (form & XFS_RTBLOCK_QUOTA)
244 fprintf(fp, (flags & HUMAN_FLAG) ?
245 "%9c %s %9c" : "%15c %s %15c",
246 ' ', form_to_string(XFS_RTBLOCK_QUOTA), ' ');
247 fputc('\n', fp);
248
249 /* line 3 */
250 snprintf(scratch, sizeof(scratch), "%s ID", typename);
251 fprintf(fp, "%-10s ", scratch);
252 if (form & XFS_BLOCK_QUOTA)
253 fprintf(fp, (flags & HUMAN_FLAG) ?
254 _(" Used Soft Hard Warn/Grace ") :
255 _(" Used Soft Hard Warn/Grace "));
256 if (form & XFS_INODE_QUOTA)
257 fprintf(fp, (flags & HUMAN_FLAG) ?
258 _(" Used Soft Hard Warn/Grace ") :
259 _(" Used Soft Hard Warn/ Grace "));
260 if (form & XFS_RTBLOCK_QUOTA)
261 fprintf(fp, (flags & HUMAN_FLAG) ?
262 _(" Used Soft Hard Warn/Grace ") :
263 _(" Used Soft Hard Warn/Grace "));
264 fputc('\n', fp);
265
266 /* line 4 */
267 for (i = 0; i < 10; i++)
268 fputc('-', fp);
269 fputc(' ', fp);
270 count = (flags & HUMAN_FLAG) ? 33 : 50;
271 if (form & XFS_BLOCK_QUOTA) {
272 for (i = 0; i < count; i++)
273 fputc('-', fp);
274 fputc(' ', fp);
275 }
276 if (form & XFS_INODE_QUOTA) {
277 for (i = 0; i < count; i++)
278 fputc('-', fp);
279 fputc(' ', fp);
280 }
281 if (form & XFS_RTBLOCK_QUOTA) {
282 for (i = 0; i < count; i++)
283 fputc('-', fp);
284 fputc(' ', fp);
285 }
286 fputc('\n', fp);
287}
288
289static int
290report_mount(
291 FILE *fp,
292 __uint32_t id,
293 char *name,
294 uint form,
295 uint type,
296 fs_path_t *mount,
297 uint flags)
298{
299 fs_disk_quota_t d;
300 char *dev = mount->fs_name;
301 char c[8], h[8], s[8];
302 uint qflags;
303 int count;
304
ec4cd312 305 if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) {
e127d47b 306 if (errno != ENOENT && errno != ENOSYS && errno != ESRCH)
ec4cd312 307 perror("XFS_GETQUOTA");
5aead01d 308 return 0;
ec4cd312 309 }
5aead01d
NS
310
311 if (flags & TERSE_FLAG) {
312 count = 0;
313 if ((form & XFS_BLOCK_QUOTA) && d.d_bcount)
314 count++;
315 if ((form & XFS_INODE_QUOTA) && d.d_icount)
316 count++;
317 if ((form & XFS_RTBLOCK_QUOTA) && d.d_rtbcount)
318 count++;
319 if (!count)
320 return 0;
321 }
322
323 if (!(flags & NO_HEADER_FLAG))
324 report_header(fp, form, type, mount, flags);
325
85dcd9a0 326 if (flags & NO_LOOKUP_FLAG) {
a265445e 327 fprintf(fp, "#%-10u", id);
85dcd9a0
ES
328 } else {
329 if (name == NULL) {
330 if (type == XFS_USER_QUOTA) {
331 struct passwd *u = getpwuid(id);
332 if (u)
333 name = u->pw_name;
334 } else if (type == XFS_GROUP_QUOTA) {
335 struct group *g = getgrgid(id);
336 if (g)
337 name = g->gr_name;
338 } else if (type == XFS_PROJ_QUOTA) {
339 fs_project_t *p = getprprid(id);
340 if (p)
341 name = p->pr_name;
342 }
343 }
a265445e 344 fprintf(fp, "%-10s", name);
85dcd9a0 345 }
a265445e 346
5aead01d
NS
347 if (form & XFS_BLOCK_QUOTA) {
348 qflags = (flags & HUMAN_FLAG);
349 if (d.d_blk_hardlimit && d.d_bcount > d.d_blk_hardlimit)
350 qflags |= LIMIT_FLAG;
351 if (d.d_blk_softlimit && d.d_bcount > d.d_blk_softlimit)
352 qflags |= QUOTA_FLAG;
353 if (flags & HUMAN_FLAG)
354 fprintf(fp, " %6s %6s %6s %02d %8s",
355 bbs_to_string(d.d_bcount, c, sizeof(c)),
356 bbs_to_string(d.d_blk_softlimit, s, sizeof(s)),
357 bbs_to_string(d.d_blk_hardlimit, h, sizeof(h)),
358 d.d_bwarns,
359 time_to_string(d.d_btimer, qflags));
360 else
361 fprintf(fp, " %10llu %10llu %10llu %02d %9s",
362 (unsigned long long)d.d_bcount >> 1,
363 (unsigned long long)d.d_blk_softlimit >> 1,
364 (unsigned long long)d.d_blk_hardlimit >> 1,
365 d.d_bwarns,
366 time_to_string(d.d_btimer, qflags));
367 }
368 if (form & XFS_INODE_QUOTA) {
369 qflags = (flags & HUMAN_FLAG);
370 if (d.d_ino_hardlimit && d.d_icount > d.d_ino_hardlimit)
371 qflags |= LIMIT_FLAG;
372 if (d.d_ino_softlimit && d.d_icount > d.d_ino_softlimit)
373 qflags |= QUOTA_FLAG;
374 if (flags & HUMAN_FLAG)
375 fprintf(fp, " %6s %6s %6s %02d %8s",
376 num_to_string(d.d_icount, c, sizeof(c)),
377 num_to_string(d.d_ino_softlimit, s, sizeof(s)),
378 num_to_string(d.d_ino_hardlimit, h, sizeof(h)),
379 d.d_iwarns,
380 time_to_string(d.d_itimer, qflags));
381 else
382 fprintf(fp, " %10llu %10llu %10llu %02d %9s",
383 (unsigned long long)d.d_icount,
384 (unsigned long long)d.d_ino_softlimit,
385 (unsigned long long)d.d_ino_hardlimit,
386 d.d_iwarns,
387 time_to_string(d.d_itimer, qflags));
388 }
389 if (form & XFS_RTBLOCK_QUOTA) {
390 qflags = (flags & HUMAN_FLAG);
391 if (d.d_rtb_hardlimit && d.d_rtbcount > d.d_rtb_hardlimit)
392 qflags |= LIMIT_FLAG;
393 if (d.d_rtb_softlimit && d.d_rtbcount > d.d_rtb_softlimit)
394 qflags |= QUOTA_FLAG;
395 if (flags & HUMAN_FLAG)
396 fprintf(fp, " %6s %6s %6s %02d %8s",
397 bbs_to_string(d.d_rtbcount, c, sizeof(c)),
398 bbs_to_string(d.d_rtb_softlimit, s, sizeof(s)),
399 bbs_to_string(d.d_rtb_hardlimit, h, sizeof(h)),
400 d.d_rtbwarns,
401 time_to_string(d.d_rtbtimer, qflags));
402 else
403 fprintf(fp, " %10llu %10llu %10llu %02d %9s",
404 (unsigned long long)d.d_rtbcount >> 1,
405 (unsigned long long)d.d_rtb_softlimit >> 1,
406 (unsigned long long)d.d_rtb_hardlimit >> 1,
407 d.d_rtbwarns,
408 time_to_string(d.d_rtbtimer, qflags));
409 }
410 fputc('\n', fp);
411 return 1;
412}
413
414static void
415report_user_mount(
416 FILE *fp,
417 uint form,
418 fs_path_t *mount,
1774874a
NS
419 uint lower,
420 uint upper,
5aead01d
NS
421 uint flags)
422{
1774874a 423 struct passwd *u;
1774874a
NS
424 uint id;
425
426 if (upper) { /* identifier range specified */
57cc6e78 427 for (id = lower; id <= upper; id++) {
a265445e 428 if (report_mount(fp, id, NULL,
1774874a
NS
429 form, XFS_USER_QUOTA, mount, flags))
430 flags |= NO_HEADER_FLAG;
431 }
432 } else {
433 setpwent();
434 while ((u = getpwent()) != NULL) {
a265445e 435 if (report_mount(fp, u->pw_uid, u->pw_name,
1774874a
NS
436 form, XFS_USER_QUOTA, mount, flags))
437 flags |= NO_HEADER_FLAG;
438 }
439 endpwent();
440 }
5aead01d 441
5aead01d
NS
442 if (flags & NO_HEADER_FLAG)
443 fputc('\n', fp);
5aead01d
NS
444}
445
446static void
447report_group_mount(
448 FILE *fp,
449 uint form,
450 fs_path_t *mount,
1774874a
NS
451 uint lower,
452 uint upper,
5aead01d
NS
453 uint flags)
454{
1774874a 455 struct group *g;
1774874a
NS
456 uint id;
457
458 if (upper) { /* identifier range specified */
57cc6e78 459 for (id = lower; id <= upper; id++) {
a265445e 460 if (report_mount(fp, id, NULL,
1774874a
NS
461 form, XFS_GROUP_QUOTA, mount, flags))
462 flags |= NO_HEADER_FLAG;
463 }
464 } else {
465 setgrent();
466 while ((g = getgrent()) != NULL) {
a265445e 467 if (report_mount(fp, g->gr_gid, g->gr_name,
1774874a
NS
468 form, XFS_GROUP_QUOTA, mount, flags))
469 flags |= NO_HEADER_FLAG;
470 }
471 }
5aead01d
NS
472 if (flags & NO_HEADER_FLAG)
473 fputc('\n', fp);
474 endgrent();
475}
476
477static void
478report_project_mount(
479 FILE *fp,
480 uint form,
481 fs_path_t *mount,
1774874a
NS
482 uint lower,
483 uint upper,
5aead01d
NS
484 uint flags)
485{
486 fs_project_t *p;
1774874a
NS
487 uint id;
488
489 if (upper) { /* identifier range specified */
57cc6e78 490 for (id = lower; id <= upper; id++) {
a265445e 491 if (report_mount(fp, id, NULL,
1774874a
NS
492 form, XFS_PROJ_QUOTA, mount, flags))
493 flags |= NO_HEADER_FLAG;
494 }
495 } else {
496 setprent();
497 while ((p = getprent()) != NULL) {
a265445e 498 if (report_mount(fp, p->pr_prid, p->pr_name,
1774874a
NS
499 form, XFS_PROJ_QUOTA, mount, flags))
500 flags |= NO_HEADER_FLAG;
501 }
502 endprent();
503 }
5aead01d 504
5aead01d
NS
505 if (flags & NO_HEADER_FLAG)
506 fputc('\n', fp);
5aead01d
NS
507}
508
509static void
510report_any_type(
511 FILE *fp,
512 uint form,
513 uint type,
514 char *dir,
1774874a
NS
515 uint lower,
516 uint upper,
5aead01d
NS
517 uint flags)
518{
519 fs_cursor_t cursor;
520 fs_path_t *mount;
521
522 if (type & XFS_USER_QUOTA) {
523 fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
546bedf4 524 while ((mount = fs_cursor_next_entry(&cursor))) {
ec4cd312
AM
525 if (xfsquotactl(XFS_QSYNC, mount->fs_name,
526 XFS_USER_QUOTA, 0, NULL) < 0
527 && errno != ENOENT && errno != ENOSYS)
528 perror("XFS_QSYNC user quota");
1774874a
NS
529 report_user_mount(fp, form, mount,
530 lower, upper, flags);
546bedf4 531 }
5aead01d
NS
532 }
533 if (type & XFS_GROUP_QUOTA) {
534 fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
546bedf4 535 while ((mount = fs_cursor_next_entry(&cursor))) {
ec4cd312
AM
536 if (xfsquotactl(XFS_QSYNC, mount->fs_name,
537 XFS_GROUP_QUOTA, 0, NULL) < 0
538 && errno != ENOENT && errno != ENOSYS)
539 perror("XFS_QSYNC group quota");
1774874a
NS
540 report_group_mount(fp, form, mount,
541 lower, upper, flags);
546bedf4 542 }
5aead01d
NS
543 }
544 if (type & XFS_PROJ_QUOTA) {
545 fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
546bedf4 546 while ((mount = fs_cursor_next_entry(&cursor))) {
ec4cd312
AM
547 if (xfsquotactl(XFS_QSYNC, mount->fs_name,
548 XFS_PROJ_QUOTA, 0, NULL) < 0
549 && errno != ENOENT && errno != ENOSYS)
550 perror("XFS_QSYNC proj quota");
1774874a
NS
551 report_project_mount(fp, form, mount,
552 lower, upper, flags);
546bedf4 553 }
5aead01d
NS
554 }
555}
556
557static int
558report_f(
559 int argc,
560 char **argv)
561{
562 FILE *fp = NULL;
fa13a00f 563 char *fname = NULL;
1774874a 564 uint lower = 0, upper = 0;
85dcd9a0 565 bool lookup = false;
5aead01d
NS
566 int c, flags = 0, type = 0, form = 0;
567
85dcd9a0 568 while ((c = getopt(argc, argv, "abdf:ghilL:NnprtuU:")) != EOF) {
5aead01d
NS
569 switch (c) {
570 case 'f':
571 fname = optarg;
572 break;
573 case 'b':
574 form |= XFS_BLOCK_QUOTA;
575 break;
576 case 'i':
577 form |= XFS_INODE_QUOTA;
578 break;
579 case 'r':
580 form |= XFS_RTBLOCK_QUOTA;
581 break;
582 case 'g':
583 type |= XFS_GROUP_QUOTA;
584 break;
585 case 'p':
586 type |= XFS_PROJ_QUOTA;
587 break;
588 case 'u':
589 type |= XFS_USER_QUOTA;
590 break;
591 case 'a':
592 flags |= ALL_MOUNTS_FLAG;
593 break;
594 case 'h':
595 flags |= HUMAN_FLAG;
596 break;
597 case 'n':
1774874a
NS
598 flags |= NO_LOOKUP_FLAG;
599 break;
600 case 'N':
5aead01d
NS
601 flags |= NO_HEADER_FLAG;
602 break;
603 case 't':
604 flags |= TERSE_FLAG;
605 break;
1774874a
NS
606 case 'L':
607 lower = (uint)atoi(optarg);
85dcd9a0 608 flags |= NO_LOOKUP_FLAG;
1774874a
NS
609 break;
610 case 'U':
611 upper = (uint)atoi(optarg);
85dcd9a0
ES
612 flags |= NO_LOOKUP_FLAG;
613 break;
614 case 'l':
615 lookup = true;
1774874a 616 break;
5aead01d
NS
617 default:
618 return command_usage(&report_cmd);
619 }
620 }
621
622 if (!form)
623 form = XFS_BLOCK_QUOTA;
624
625 if (!type)
626 type = XFS_USER_QUOTA | XFS_GROUP_QUOTA | XFS_PROJ_QUOTA;
627
85dcd9a0
ES
628 if (lookup)
629 flags &= ~NO_LOOKUP_FLAG;
630
5aead01d
NS
631 if ((fp = fopen_write_secure(fname)) == NULL)
632 return 0;
633
fa13a00f
NS
634 if (argc == optind) {
635 if (flags & ALL_MOUNTS_FLAG)
636 report_any_type(fp, form, type, NULL,
637 lower, upper, flags);
a14d4093 638 else if (fs_path && (fs_path->fs_flags & FS_MOUNT_POINT))
fa13a00f
NS
639 report_any_type(fp, form, type, fs_path->fs_dir,
640 lower, upper, flags);
641 } else while (argc > optind) {
642 report_any_type(fp, form, type, argv[optind++],
643 lower, upper, flags);
1774874a 644 }
5aead01d
NS
645
646 if (fname)
647 fclose(fp);
648 return 0;
649}
650
651void
652report_init(void)
653{
ad765595 654 dump_cmd.name = "dump";
5aead01d
NS
655 dump_cmd.cfunc = dump_f;
656 dump_cmd.argmin = 0;
657 dump_cmd.argmax = -1;
658 dump_cmd.args = _("[-gpu] [-f file]");
659 dump_cmd.oneline = _("dump quota information for backup utilities");
660 dump_cmd.help = dump_help;
661
ad765595
AM
662 report_cmd.name = "report";
663 report_cmd.altname = "repquota";
5aead01d
NS
664 report_cmd.cfunc = report_f;
665 report_cmd.argmin = 0;
666 report_cmd.argmax = -1;
19473a2a 667 report_cmd.flags = CMD_FLAG_GLOBAL;
5aead01d
NS
668 report_cmd.args = _("[-bir] [-gpu] [-ahnt] [-f file]");
669 report_cmd.oneline = _("report filesystem quota information");
670 report_cmd.help = report_help;
671
672 if (expert) {
673 add_command(&dump_cmd);
674 add_command(&report_cmd);
675 }
676}