#include "config.h" #include #include #include #include #include #include #include #include "pot.h" #include "common.h" #include "quotasys.h" #include "quotaio.h" #define FL_USER 1 /* sync user quotas */ #define FL_GROUP 2 /* sync group quotas */ #define FL_ALL 4 /* sync quotas on all filesystems */ #define FL_PROJECT 8 /* sync group quotas */ static int flags, fmt = -1; static char **mnt; static int mntcnt; char *progname; static void usage(int status) { printf(_( "%1$s: Utility for syncing quotas.\n" "Usage: %1$s [-ugP] mount-point...\n" " or: %1$s [-ugP] -a\n" " or: %1$s -h | -V\n" "\n" ), progname); printf(_( "Options:\n" "-u, --user synchronize user quotas\n" "-g, --group synchronize group quotas\n" "-P, --project synchronize project quotas\n" "-a, --all synchronize quotas for all mounted file systems\n" "-h, --help display this help message and exit\n" "-V, --version display version information and exit\n" "\n" )); printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT); exit(status); } static void parse_options(int argcnt, char **argstr) { int ret; struct option long_opts[] = { { "user", 0, NULL, 'u' }, { "group", 0, NULL, 'g' }, { "project", 0, NULL, 'P' }, { "all", 0, NULL, 'a' }, { "version", 0, NULL, 'V' }, { "help", 0, NULL, 'h' }, { NULL, 0, NULL, 0 } }; while ((ret = getopt_long(argcnt, argstr, "ahugPV", long_opts, NULL)) != -1) { switch (ret) { case '?': usage(EXIT_FAILURE); case 'h': usage(EXIT_SUCCESS); case 'V': version(); exit(EXIT_SUCCESS); case 'u': flags |= FL_USER; break; case 'g': flags |= FL_GROUP; break; case 'P': flags |= FL_PROJECT; break; case 'a': flags |= FL_ALL; break; } } if ((flags & FL_ALL && optind != argcnt) || (!(flags & FL_ALL) && optind == argcnt)) { fputs(_("Bad number of arguments.\n"), stderr); usage(EXIT_FAILURE); } if (!(flags & FL_ALL)) { mnt = argstr + optind; mntcnt = argcnt - optind; } if (!(flags & (FL_USER | FL_GROUP))) flags |= FL_USER; } static int sync_one(int type, char *dev) { int qcmd = QCMD(Q_SYNC, type); return quotactl(qcmd, dev, 0, NULL); } static int syncquotas(int type) { struct quota_handle **handles, *h; int i, ret = 0; if (flags & FL_ALL) { if (sync_one(type, NULL) < 0) { errstr(_("%s quota sync failed: %s\n"), _(type2name(type)), strerror(errno)); ret = -1; } return ret; } handles = create_handle_list(mntcnt, mnt, type, fmt, IOI_READONLY, MS_LOCALONLY | MS_NO_AUTOFS); for (i = 0; handles[i]; i++) { h = handles[i]; if (sync_one(type, h->qh_quotadev)) { errstr(_("%s quota sync failed for %s: %s\n"), _(type2name(type)), h->qh_quotadev, strerror(errno)); ret = -1; } } dispose_handle_list(handles); return ret; } int main(int argc, char **argv) { int ret = EXIT_SUCCESS; gettexton(); progname = basename(argv[0]); parse_options(argc, argv); init_kernel_interface(); if (flags & FL_USER) if (syncquotas(USRQUOTA)) ret = EXIT_FAILURE; if (flags & FL_GROUP) if (syncquotas(GRPQUOTA)) ret = EXIT_FAILURE; if (flags & FL_PROJECT) if (syncquotas(PRJQUOTA)) ret = EXIT_FAILURE; return ret; }