diff options
Diffstat (limited to 'convertquota.c')
-rw-r--r-- | convertquota.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/convertquota.c b/convertquota.c new file mode 100644 index 0000000..26f34e9 --- /dev/null +++ b/convertquota.c @@ -0,0 +1,136 @@ +/* + * + * Utility for converting quota file from old to new format + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +#include <asm/byteorder.h> + +#include "pot.h" +#include "common.h" +#include "quotaio.h" +#include "quotasys.h" +#include "quota.h" +#include "bylabel.h" + +char *mntpoint; +int ucv, gcv; +struct quota_handle *qn; /* Handle of new file */ + +void parse_options(int argcnt, char **argstr) +{ + int ret; + char *slash = strrchr(argstr[0], '/'), cmdname[PATH_MAX]; + + if (!slash) + slash = argstr[0]; + else + slash++; + sstrncpy(cmdname, slash, sizeof(cmdname)); + while ((ret = getopt(argcnt, argstr, "Vugh:")) != EOF) { + switch (ret) { + case '?': + case 'h': +usage: + printf(_("Utility for converting quota files.\nUsage:\n%s [-u] [-g] mountpoint\n"), cmdname); + printf(_("Bugs to %s\n"), MY_EMAIL); + exit(1); + case 'V': + version(); + exit(0); + case 'u': + ucv = 1; + break; + case 'g': + gcv = 1; + break; + } + } + if (optind + 1 != argcnt) { + puts(_("Bad number of arguments.")); + goto usage; + } + if (!(ucv | gcv)) + ucv = 1; + mntpoint = argstr[optind]; +} + +int convert_dquot(struct dquot *dquot) +{ + struct dquot newdquot; + + memset(&newdquot, 0, sizeof(newdquot)); + newdquot.dq_id = dquot->dq_id; + newdquot.dq_h = qn; + newdquot.dq_dqb.dqb_ihardlimit = dquot->dq_dqb.dqb_ihardlimit; + newdquot.dq_dqb.dqb_isoftlimit = dquot->dq_dqb.dqb_isoftlimit; + newdquot.dq_dqb.dqb_curinodes = dquot->dq_dqb.dqb_curinodes; + newdquot.dq_dqb.dqb_bhardlimit = dquot->dq_dqb.dqb_bhardlimit; + newdquot.dq_dqb.dqb_bsoftlimit = dquot->dq_dqb.dqb_bsoftlimit; + newdquot.dq_dqb.dqb_curspace = dquot->dq_dqb.dqb_curspace; + newdquot.dq_dqb.dqb_btime = dquot->dq_dqb.dqb_btime; + newdquot.dq_dqb.dqb_itime = dquot->dq_dqb.dqb_itime; + if (qn->qh_ops->commit_dquot(&newdquot) < 0) { + fprintf(stderr, _("Can't commit dquot for id %u: %s\n"), (uint)dquot->dq_id, strerror(errno)); + return -1; + } + return 0; +} + +void convert_file(int type) +{ + struct quota_handle *qo; + char *qfname, namebuf[PATH_MAX]; + FILE *mntf; + struct mntent *mnt; + const char *dev; + + if (!(mntf = setmntent(MOUNTED, "r"))) + die(2, _("Can't open %s: %s\n"), MOUNTED, strerror(errno)); + while ((mnt = getmntent(mntf))) { + if (!(dev = get_device_name(mnt->mnt_fsname))) + continue; + if (!strcmp(dev, mntpoint) || !strcmp(mnt->mnt_dir, mntpoint)) + break; + } + if (!mnt) + die(1, _("Can't find given mountpoint %s\n"), mntpoint); + if (!(qo = init_io(mnt, type, QF_VFSOLD))) { + fprintf(stderr, _("Can't open old format file for %ss on %s\n"), type2name(type), mntpoint); + return; + } + if (!(qn = new_io(mnt, type, QF_VFSV0))) { + fprintf(stderr, _("Can't create file for %ss for new format on %s: %s\n"), type2name(type), mntpoint, strerror(errno)); + end_io(qo); + return; + } + if (qo->qh_ops->scan_dquots(qo, convert_dquot) >= 0) { /* Conversion succeeded? */ + qfname = get_qf_name(mnt, type, QF_VFSV0); + strcpy(namebuf, qfname); + sstrncat(namebuf, ".new", sizeof(namebuf)); + if (rename(namebuf, qfname) < 0) + fprintf(stderr, _("Can't rename new quotafile %s to name %s: %s\n"), namebuf, qfname, strerror(errno)); + free(qfname); + } + endmntent(mntf); + end_io(qo); + end_io(qn); +} + +int main(int argcnt, char **argstr) +{ + parse_options(argcnt, argstr); + if (ucv) + convert_file(USRQUOTA); + if (ucv) + convert_file(GRPQUOTA); + return 0; +} + |