diff options
author | jkar8572 <jkar8572> | 2001-08-15 20:13:42 +0000 |
---|---|---|
committer | jkar8572 <jkar8572> | 2001-08-15 20:13:42 +0000 |
commit | 59157c4442d31775624ad5b8b0bd3e0e3548b624 (patch) | |
tree | bb6267b7fe46ef8f5da69c11827e9cfd69e612e1 | |
parent | 805ee8ff8b05468a2f2ce09db619bded1d6a687d (diff) | |
download | linuxquota-59157c4442d31775624ad5b8b0bd3e0e3548b624.tar.gz |
Fixed a few error messages.
Implemented new mountpoint scanning.
Implemented caching for scanning in old quota format.
Implemented automatic choice of appropriate units in repquota, quota.
-rw-r--r-- | common.c | 41 | ||||
-rw-r--r-- | common.h | 9 | ||||
-rw-r--r-- | convertquota.c | 40 | ||||
-rw-r--r-- | edquota.c | 4 | ||||
-rw-r--r-- | quot.c | 48 | ||||
-rw-r--r-- | quota.1 | 13 | ||||
-rw-r--r-- | quota.c | 35 | ||||
-rw-r--r-- | quotacheck.c | 119 | ||||
-rw-r--r-- | quotaio.c | 9 | ||||
-rw-r--r-- | quotaio_v1.c | 33 | ||||
-rw-r--r-- | quotaio_v1.h | 2 | ||||
-rw-r--r-- | quotaon.c | 40 | ||||
-rw-r--r-- | quotaon_xfs.c | 2 | ||||
-rw-r--r-- | quotasys.c | 337 | ||||
-rw-r--r-- | quotasys.h | 19 | ||||
-rw-r--r-- | repquota.8 | 8 | ||||
-rw-r--r-- | repquota.c | 32 | ||||
-rw-r--r-- | rquota_client.c | 5 | ||||
-rw-r--r-- | rquota_server.c | 62 | ||||
-rw-r--r-- | rquota_svc.c | 20 | ||||
-rw-r--r-- | setquota.c | 2 |
21 files changed, 542 insertions, 338 deletions
@@ -42,7 +42,18 @@ void *smalloc(size_t size) void *ret = malloc(size); if (!ret) { - puts("Not enough memory.\n"); + fputs("Not enough memory.\n", stderr); + exit(3); + } + return ret; +} + +void *srealloc(void *ptr, size_t size) +{ + void *ret = realloc(ptr, size); + + if (!ret) { + fputs("Not enough memory.\n", stderr); exit(3); } return ret; @@ -71,34 +82,6 @@ char *sstrdup(const char *s) return r; } -int devcmp(const char *mtab_dev, char *user_dev) -{ - struct stat mtab_stat, user_stat; - - if (stat(mtab_dev, &mtab_stat) < 0 || stat(user_dev, &user_stat) < 0) - return (strcmp(mtab_dev, user_dev) == 0); - if (!S_ISBLK(mtab_stat.st_mode) || !S_ISBLK(user_stat.st_mode)) - return 0; - if (mtab_stat.st_rdev != user_stat.st_rdev) - return 0; - return 1; -} - -int dircmp(char *mtab_dir, char *user_dir) -{ - struct stat mtab_stat, user_stat; - - if (stat(mtab_dir, &mtab_stat) < 0 || stat(user_dir, &user_stat) < 0) - return (strcmp(mtab_dir, user_dir) == 0); - if (!S_ISDIR(mtab_stat.st_mode) || !S_ISDIR(user_stat.st_mode)) - return 0; - if (mtab_stat.st_dev != user_stat.st_dev) - return 0; - if (mtab_stat.st_ino != user_stat.st_ino) - return 0; - return 1; -} - void version(void) { printf(_("Quota utilities version %s.\n"), QUOTA_VERSION); @@ -21,6 +21,9 @@ void errstr(char *, ...); /* malloc() with error check */ void *smalloc(size_t); +/* realloc() with error check */ +void *srealloc(void *, size_t); + /* Safe strncpy - always finishes string */ void sstrncpy(char *, const char *, int); @@ -30,12 +33,6 @@ void sstrncat(char *, const char *, int); /* Safe version of strdup() */ char *sstrdup(const char *s); -/* Test whether two file names are for the same device */ -int devcmp(const char *mtab_dev, char *user_dev); - -/* Test whether two file names are for the same directory */ -int dircmp(char *mtab_dir, char *user_dir); - /* Print version string */ void version(void); diff --git a/convertquota.c b/convertquota.c index bb7ac07..ceaf6e7 100644 --- a/convertquota.c +++ b/convertquota.c @@ -95,35 +95,19 @@ int convert_dquot(struct dquot *dquot, char *name) return 0; } -void convert_file(int type) +void convert_file(int type, struct mntent *mnt) { 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 (devcmp(dev, mntpoint) || dircmp(mnt->mnt_dir, mntpoint)) { - free((void *)dev); - break; - } - free((void *)dev); - } - if (!mnt) - die(1, _("Can't find given mountpoint %s\n"), mntpoint); + if (!(qo = init_io(mnt, type, QF_VFSOLD, 1))) { errstr(_("Can't open old format file for %ss on %s\n"), - type2name(type), mntpoint); + type2name(type), mnt->mnt_dir); return; } if (!(qn = new_io(mnt, type, QF_VFSV0))) { errstr(_("Can't create file for %ss for new format on %s: %s\n"), - type2name(type), mntpoint, strerror(errno)); + type2name(type), mnt->mnt_dir, strerror(errno)); end_io(qo); return; } @@ -136,23 +120,29 @@ void convert_file(int type) namebuf, qfname, strerror(errno)); free(qfname); } - endmntent(mntf); end_io(qo); end_io(qn); } int main(int argc, char **argv) { + struct mntent *mnt; + gettexton(); progname = basename(argv[0]); parse_options(argc, argv); - + if (init_mounts_scan(1, &mntpoint) < 0) + return 1; + if (!(mnt = get_next_mount())) { + end_mounts_scan(); + return 1; + } if (ucv) - convert_file(USRQUOTA); - + convert_file(USRQUOTA, mnt); if (gcv) - convert_file(GRPQUOTA); + convert_file(GRPQUOTA, mnt); + end_mounts_scan(); return 0; } @@ -34,7 +34,7 @@ #ident "$Copyright: (c) 1980, 1990 Regents of the University of California. $" #ident "$Copyright: All rights reserved. $" -#ident "$Id: edquota.c,v 1.5 2001/07/16 03:24:49 jkar8572 Exp $" +#ident "$Id: edquota.c,v 1.6 2001/08/15 20:13:42 jkar8572 Exp $" /* * Disk quota editor. @@ -73,7 +73,7 @@ void usage(void) _("\tedquota -g [-F formatname] [-p groupname] groupname ...\n"), _("\tedquota [-u] [-F formatname] -t\n"), _("\tedquota -g [-F formatname] -t\n")); #endif - errstr(_("Bugs to: %s\n"), MY_EMAIL); + fprintf(stderr, _("Bugs to: %s\n"), MY_EMAIL); exit(1); } @@ -55,6 +55,7 @@ #include "common.h" #include "mntopt.h" #include "bylabel.h" +#include "quotasys.h" #define TSIZE 500 __uint64_t sizes[TSIZE]; @@ -69,7 +70,7 @@ static int vflag; static time_t now; char *progname; -static void mounttable(char *); +static void mounttable(void); static char *idname(__uint32_t, int); static void report(const char *, char *, int); static void creport(const char *, char *); @@ -118,55 +119,32 @@ int main(int argc, char **argv) usage(); if (!uflag && !gflag) uflag++; - if (aflag) - mounttable(NULL); - else { - while (optind < argc) - mounttable(argv[optind++]); - } + if (init_mounts_scan(aflag ? 0 : argc - optind, argv + optind) < 0) + return 1; + mounttable(); + end_mounts_scan(); return 0; } -static void mounttable(char *entry) +static void mounttable(void) { + int doit = 0; struct mntent *mntp; - const char *dev; - FILE *mtab; - int doit; - - if ((mtab = setmntent(MOUNTED, "r")) == NULL) { - errstr(_("no " MOUNTED " file\n")); - exit(1); - } - while ((mntp = getmntent(mtab)) != NULL) { - doit = 0; - dev = get_device_name(mntp->mnt_fsname); - if (entry && !dircmp(mntp->mnt_dir, entry) && !devcmp(dev, entry)) { - free((char *)dev); - continue; - } + while ((mntp = get_next_mount())) { /* Currently, only XFS is implemented... */ if (strcmp(mntp->mnt_type, MNTTYPE_XFS) == 0) { - checkXFS(dev, mntp->mnt_dir); + checkXFS(mntp->mnt_fsname, mntp->mnt_dir); doit = 1; } /* ...additional filesystems types here. */ if (doit) { - if (cflag) creport(dev, mntp->mnt_dir); - if (!cflag && uflag) report(dev, mntp->mnt_dir, 0); - if (!cflag && gflag) report(dev, mntp->mnt_dir, 1); - } - free((char *)dev); - if (entry != NULL) { - entry = NULL; /* found, bail out */ - break; + if (cflag) creport(mntp->mnt_fsname, mntp->mnt_dir); + if (!cflag && uflag) report(mntp->mnt_fsname, mntp->mnt_dir, 0); + if (!cflag && gflag) report(mntp->mnt_fsname, mntp->mnt_dir, 1); } } - if (entry != NULL) - errstr(_("cannot locate block device for %s\n"), entry); - endmntent(mtab); } static int qcmp(du_t * p1, du_t * p2) @@ -6,21 +6,21 @@ quota [ .B -F .I format-name ] [ -.B -guv | q +.B -guvs | q ] .br quota [ .B -F .I format-name ] [ -.B -uv | q +.B -uvs | q ] user .br quota [ .B -F .I format-name ] [ -.B -gv | q +.B -gvs | q ] group .SH DESCRIPTION .B Quota @@ -58,7 +58,12 @@ flag is equivalent to the default. will display quotas on filesystems where no storage is allocated. .TP -.B -q +.B \-s +flag will make +.BR quota(1) +try to choose units for showing limits, used space and used inodes. +.TP +.B \-q Print a more terse message, containing only information on filesystems where usage is over quota. @@ -34,7 +34,7 @@ #ident "$Copyright: (c) 1980, 1990 Regents of the University of California. $" #ident "$Copyright: All rights reserved. $" -#ident "$Id: quota.c,v 1.6 2001/07/17 21:10:57 jkar8572 Exp $" +#ident "$Id: quota.c,v 1.7 2001/08/15 20:13:42 jkar8572 Exp $" /* * Disk quota reporting program. @@ -60,7 +60,7 @@ #include "pot.h" #include "common.h" -int qflag, vflag, fmt = -1; +int qflag, vflag, sflag, fmt = -1; char *progname; void usage(void); @@ -76,7 +76,7 @@ int main(int argc, char **argv) gettexton(); progname = basename(argv[0]); - while ((ret = getopt(argc, argv, "guqvVF:")) != -1) { + while ((ret = getopt(argc, argv, "guqvsVF:")) != -1) { switch (ret) { case 'g': gflag++; @@ -94,6 +94,9 @@ int main(int argc, char **argv) if ((fmt = name2fmt(optarg)) == QF_ERROR) /* Error? */ exit(1); break; + case 's': + sflag++; + break; case 'V': version(); exit(0); @@ -137,10 +140,10 @@ int main(int argc, char **argv) void usage(void) { errstr( "%s%s%s", - _("Usage: quota [-guqv] [-F quotaformat]\n"), - _("\tquota [-qv] [-F quotaformat] -u username ...\n"), - _("\tquota [-qv] [-F quotaformat] -g groupname ...\n")); - errstr(_("Bugs to: %s\n"), MY_EMAIL); + _("Usage: quota [-guqvs] [-F quotaformat]\n"), + _("\tquota [-qvs] [-F quotaformat] -u username ...\n"), + _("\tquota [-qvs] [-F quotaformat] -g groupname ...\n")); + fprintf(stderr, _("Bugs to: %s\n"), MY_EMAIL); exit(1); } @@ -197,6 +200,8 @@ int showquotas(int type, qid_t id) continue; } if (vflag || q->dq_dqb.dqb_curspace || q->dq_dqb.dqb_curinodes) { + char numbuf[3][MAXNUMLEN]; + if (!lines++) heading(type, id, name, ""); if (strlen(q->dq_h->qh_quotadev) > 15) @@ -205,14 +210,18 @@ int showquotas(int type, qid_t id) printf("%15s", q->dq_h->qh_quotadev); if (msgb) difftime2str(q->dq_dqb.dqb_btime, timebuf); - printf(" %7Lu%c %6Lu %7Lu %7s", (long long)toqb(q->dq_dqb.dqb_curspace), - msgb ? '*' : ' ', (long long)q->dq_dqb.dqb_bsoftlimit, - (long long)q->dq_dqb.dqb_bhardlimit, msgb ? timebuf : ""); + space2str(toqb(q->dq_dqb.dqb_curspace), numbuf[0], sflag); + space2str(q->dq_dqb.dqb_bsoftlimit, numbuf[1], sflag); + space2str(q->dq_dqb.dqb_bhardlimit, numbuf[2], sflag); + printf(" %7s%c %6s %7s %7s", numbuf[0], msgb ? '*' : ' ', numbuf[1], + numbuf[2], msgb ? timebuf : ""); if (msgi) difftime2str(q->dq_dqb.dqb_itime, timebuf); - printf(" %7Lu%c %6Lu %7Lu %7s\n", (long long)q->dq_dqb.dqb_curinodes, - msgi ? '*' : ' ', (long long)q->dq_dqb.dqb_isoftlimit, - (long long)q->dq_dqb.dqb_ihardlimit, msgi ? timebuf : ""); + number2str(q->dq_dqb.dqb_curinodes, numbuf[0], sflag); + number2str(q->dq_dqb.dqb_isoftlimit, numbuf[1], sflag); + number2str(q->dq_dqb.dqb_ihardlimit, numbuf[2], sflag); + printf(" %7s%c %6s %7s %7s\n", numbuf[0], msgi ? '*' : ' ', numbuf[1], + numbuf[2], msgi ? timebuf : ""); continue; } } diff --git a/quotacheck.c b/quotacheck.c index 1ea81b9..f0a2fce 100644 --- a/quotacheck.c +++ b/quotacheck.c @@ -8,7 +8,7 @@ * New quota format implementation - Jan Kara <jack@suse.cz> - Sponsored by SuSE CR */ -#ident "$Id: quotacheck.c,v 1.15 2001/08/10 11:23:14 jkar8572 Exp $" +#ident "$Id: quotacheck.c,v 1.16 2001/08/15 20:13:42 jkar8572 Exp $" #include <dirent.h> #include <stdio.h> @@ -534,7 +534,7 @@ int ask_yn(char *q, int def) } /* Do checks and buffer quota file into memory */ -static int process_file(char *mnt_fsname, struct mntent *mnt, int type) +static int process_file(struct mntent *mnt, int type) { char *qfname = NULL; int fd = -1, ret; @@ -542,7 +542,7 @@ static int process_file(char *mnt_fsname, struct mntent *mnt, int type) debug(FL_DEBUG | FL_VERBOSE, _("Going to check %s quota file of %s\n"), type2name(type), mnt->mnt_dir); - if (kern_quota_on(mnt_fsname, type, (1 << cfmt)) > 0) { /* Is quota enabled? */ + if (kern_quota_on(mnt->mnt_fsname, type, (1 << cfmt)) > 0) { /* Is quota enabled? */ if (!(flags & FL_FORCE)) { if (flags & FL_INTERACTIVE) { printf(_("Quota for %ss is enabled on mountpoint %s so quotacheck might damage the file.\n"), type2name(type), mnt->mnt_dir); @@ -557,15 +557,14 @@ Please turn quotas off or use -f to force checking.\n"), type2name(type), mnt->mnt_dir); } /* At least sync quotas so damage will be smaller */ - if (quotactl(QCMD(Q_SYNC, type), mnt_fsname, 0, NULL) < 0) - die(4, _("Error while syncing quotas on %s: %s\n"), mnt_fsname, strerror(errno)); + if (quotactl(QCMD(Q_SYNC, type), mnt->mnt_fsname, 0, NULL) < 0) + die(4, _("Error while syncing quotas on %s: %s\n"), mnt->mnt_fsname, strerror(errno)); } if (!(flags & FL_NEWFILE)) { /* Need to really buffer file? */ qfname = get_qf_name(mnt, type, cfmt); if (!qfname) { - errstr(_("Cannot get quotafile name for %s\n"), - mnt_fsname); + errstr(_("Cannot get quotafile name for %s\n"), mnt->mnt_fsname); return -1; } if ((fd = open(qfname, O_RDONLY)) < 0) { @@ -580,8 +579,7 @@ Please turn quotas off or use -f to force checking.\n"), memset(old_info + type, 0, sizeof(old_info[type])); switch (cfmt) { case QF_TOONEW: - errstr(_("Too new quotafile format on %s\n"), - mnt_fsname); + errstr(_("Too new quotafile format on %s\n"), mnt->mnt_fsname); ret = -1; break; case QF_VFSOLD: @@ -656,7 +654,7 @@ static int rename_files(struct mntent *mnt, int type) * quota file. As quotafiles doesn't account to quotas we don't have to * bother about accounting new blocks for quota file */ -static int dump_to_file(char *mnt_fsname, struct mntent *mnt, int type) +static int dump_to_file(struct mntent *mnt, int type) { struct dquot *dquot; uint i; @@ -687,21 +685,21 @@ static int dump_to_file(char *mnt_fsname, struct mntent *mnt, int type) } if (rename_files(mnt, type) < 0) return -1; - if (cfmt == kern_quota_on(mnt_fsname, type, 1 << cfmt)) { /* Quota turned on? */ + if (cfmt == kern_quota_on(mnt->mnt_fsname, type, 1 << cfmt)) { /* Quota turned on? */ char *filename; filename = get_qf_name(mnt, type, cfmt); - if (quotactl(QCMD(Q_QUOTAOFF, type), mnt_fsname, 0, NULL) - || quotactl(QCMD(Q_QUOTAON, type), mnt_fsname, 0, filename)) + if (quotactl(QCMD(Q_QUOTAOFF, type), mnt->mnt_fsname, 0, NULL) + || quotactl(QCMD(Q_QUOTAON, type), mnt->mnt_fsname, 0, filename)) errstr(_("Cannot turn %s quotas on %s off and on: %s\nKernel won't know about changes quotacheck did.\n"), - type2name(type), mnt_fsname, strerror(errno)); + type2name(type), mnt->mnt_fsname, strerror(errno)); free(filename); } return 0; } /* Buffer quotafile, run filesystem scan, dump quotafiles */ -static void check_dir(char *mnt_fsname, struct mntent *mnt) +static void check_dir(struct mntent *mnt) { struct stat st; int remounted = 0; @@ -715,14 +713,14 @@ static void check_dir(char *mnt_fsname, struct mntent *mnt) cur_dev = st.st_dev; files_done = dirs_done = 0; if (ucheck) { - if (process_file(mnt_fsname, mnt, USRQUOTA) >= 0) + if (process_file(mnt, USRQUOTA) >= 0) add_to_quota(USRQUOTA, st.st_ino, st.st_uid, st.st_gid, st.st_mode, st.st_nlink, qspace); else ucheck = 0; } if (gcheck) { - if (process_file(mnt_fsname, mnt, GRPQUOTA) >= 0) + if (process_file(mnt, GRPQUOTA) >= 0) add_to_quota(GRPQUOTA, st.st_ino, st.st_uid, st.st_gid, st.st_mode, st.st_nlink, qspace); else @@ -756,13 +754,13 @@ Please stop all programs writing to filesystem or use -m flag to force checking. remounted = 1; debug(FL_DEBUG | FL_VERBOSE, _("Filesystem remounted read-only\n")); } - debug(FL_VERBOSE, _("Scanning %s [%s] "), mnt_fsname, mnt->mnt_dir); + debug(FL_VERBOSE, _("Scanning %s [%s] "), mnt->mnt_fsname, mnt->mnt_dir); #if defined(EXT2_DIRECT) if (!strcmp(mnt->mnt_type, MNTTYPE_EXT2) || !strcmp(mnt->mnt_type, MNTTYPE_EXT3)) { - if (ext2_direct_scan(mnt_fsname) < 0) + if (ext2_direct_scan(mnt->mnt_fsname) < 0) goto out; } - else if (mnt_fsname) { + else { #else if (mnt->mnt_dir) { #endif @@ -780,10 +778,10 @@ Please stop all programs writing to filesystem or use -m flag to force checking. debug(FL_DEBUG | FL_VERBOSE, _("Filesystem remounted RW.\n")); } if (ucheck) - dump_to_file(mnt_fsname, mnt, USRQUOTA); + dump_to_file(mnt, USRQUOTA); if (gcheck) - dump_to_file(mnt_fsname, mnt, GRPQUOTA); - out: + dump_to_file(mnt, GRPQUOTA); +out: remove_list(); } @@ -806,66 +804,43 @@ static int detect_filename_format(struct mntent *mnt, int type) static void check_all(void) { - FILE *mntf; struct mntent *mnt; - const char *mnt_fslabel; - char *devlist[MAXMNTPOINTS]; - int gotmnt = 0, i, checked = 0; - - if (!(mntf = setmntent(MOUNTED, "r"))) - die(2, _("Cannot open %s: %s\n"), MOUNTED, strerror(errno)); - while ((mnt = getmntent(mntf))) { - if (gotmnt == MAXMNTPOINTS) - die(3, _("Too many mountpoints. Please report to: %s\n"), MY_EMAIL); - if (!(devlist[gotmnt] = (char *)get_device_name(mnt->mnt_fsname))) + int checked = 0; + + if (init_mounts_scan((flags & FL_ALL) ? 0 : 1, &mntpoint) < 0) + die(2, _("Can't initialize mountpoint scan.\n")); + while ((mnt = get_next_mount())) { + if (flags & FL_ALL && flags & FL_NOROOT && !strcmp(mnt->mnt_dir, "/")) continue; - for (i = 0; i < gotmnt && !devcmp(devlist[i], devlist[gotmnt]); i++); - /* We already have this mountpoint? */ - if (i < gotmnt) { - free(devlist[gotmnt]); + if (!strcmp(mnt->mnt_type, MNTTYPE_XFS)) { + debug(FL_DEBUG | FL_VERBOSE, _("Skipping %s [%s]\n"), mnt->mnt_fsname, mnt->mnt_dir); continue; } - gotmnt++; - if ((mnt_fslabel = strchr(mnt->mnt_fsname, '='))) - mnt_fslabel++; + cfmt = fmt; + if (uwant && hasquota(mnt, USRQUOTA)) + ucheck = 1; else - mnt_fslabel = devlist[gotmnt - 1]; - if ((flags & FL_ALL && (!(flags & FL_NOROOT) || strcmp(mnt->mnt_dir, "/"))) || - (mntpoint && (devcmp(mntpoint, devlist[gotmnt - 1]) || dircmp(mntpoint, mnt->mnt_dir)))) { - if (!strcmp(mnt->mnt_type, MNTTYPE_XFS) || - !strcmp(mnt->mnt_type, MNTTYPE_NFS)) { - debug(FL_DEBUG | FL_VERBOSE, _("Skipping %s [%s]\n"), mnt_fslabel, - mnt->mnt_dir); - continue; - } - cfmt = fmt; - if (uwant && hasquota(mnt, USRQUOTA)) - ucheck = 1; - else - ucheck = 0; - if (gwant && hasquota(mnt, GRPQUOTA)) - gcheck = 1; - else - gcheck = 0; - if (!ucheck && !gcheck) + ucheck = 0; + if (gwant && hasquota(mnt, GRPQUOTA)) + gcheck = 1; + else + gcheck = 0; + if (!ucheck && !gcheck) + continue; + if (cfmt == -1) { + if ((cfmt = detect_filename_format(mnt, ucheck ? USRQUOTA : GRPQUOTA)) == -1) { + errstr(_("Cannot guess format from filename on %s. Please specify format on commandline.\n"), + mnt->mnt_fsname); continue; - if (cfmt == -1) { - if ((cfmt = detect_filename_format(mnt, ucheck ? USRQUOTA : GRPQUOTA)) == -1) { - errstr(_("Cannot guess format from filename on %s. Please specify format on commandline.\n"), - mnt_fslabel); - continue; - } - debug(FL_DEBUG | FL_VERBOSE, _("Detected quota format %s\n"), fmt2name(cfmt)); } - checked++; - check_dir(devlist[gotmnt - 1], mnt); + debug(FL_DEBUG | FL_VERBOSE, _("Detected quota format %s\n"), fmt2name(cfmt)); } + checked++; + check_dir(mnt); } - endmntent(mntf); + end_mounts_scan(); if (!checked) errstr(_("Can't find filesystem to check or filesystem not mounted with quota option.\n")); - for (i = 0; i < gotmnt; i++) - free(devlist[i]); } int main(int argc, char **argv) @@ -126,13 +126,12 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt, int flags) /* Check file format */ h->qh_fmt = detect_qf_format(fd, type); if (h->qh_fmt == -2) { - errstr(_("Quotafile format too new in %s\n"), - qfname); + errstr(_("Quotafile format too new in %s\n"), qfname); goto out_lock; } if (fmt != -1 && h->qh_fmt != fmt) { errstr(_("Quotafile format detected differs from the specified one (or the one kernel uses on the file).\n")); - goto out_handle; + goto out_lock; } } else { @@ -151,10 +150,10 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt, int flags) goto out_lock; } return h; - out_lock: +out_lock: if (fd != -1) flock(fd, LOCK_UN); - out_handle: +out_handle: if (qfname) free(qfname); free(h); diff --git a/quotaio_v1.c b/quotaio_v1.c index c3165b9..93b77b8 100644 --- a/quotaio_v1.c +++ b/quotaio_v1.c @@ -34,7 +34,7 @@ #ident "$Copyright: (c) 1980, 1990 Regents of the University of California. $" #ident "$Copyright: All rights reserved. $" -#ident "$Id: quotaio_v1.c,v 1.6 2001/07/17 21:02:55 jkar8572 Exp $" +#ident "$Id: quotaio_v1.c,v 1.7 2001/08/15 20:13:42 jkar8572 Exp $" #include <unistd.h> #include <errno.h> @@ -282,11 +282,13 @@ static int v1_commit_dquot(struct dquot *dquot) /* * Scan all dquots in file and call callback on each */ +#define SCANBUFSIZE 256 + static int v1_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct dquot *, char *)) { - int rd; - char name[MAXNAMELEN]; - struct v1_disk_dqblk ddqblk; + int rd, scanbufpos = 0, scanbufsize = 0; + char name[MAXNAMELEN], scanbuf[sizeof(struct v1_disk_dqblk)*SCANBUFSIZE]; + struct v1_disk_dqblk *ddqblk; struct dquot *dquot = get_empty_dquot(); qid_t id = 0; @@ -297,13 +299,23 @@ static int v1_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct d memset(dquot, 0, sizeof(*dquot)); dquot->dq_h = h; lseek(h->qh_fd, 0, SEEK_SET); - for(id = 0; (rd = read(h->qh_fd, &ddqblk, sizeof(ddqblk))) == sizeof(ddqblk); id++) { - if ((ddqblk.dqb_ihardlimit | ddqblk.dqb_isoftlimit | - ddqblk.dqb_bhardlimit | ddqblk.dqb_bsoftlimit | - ddqblk.dqb_curblocks | ddqblk.dqb_curinodes | - ddqblk.dqb_itime | ddqblk.dqb_btime) == 0) + for(id = 0; ; id++, scanbufpos++) { + if (scanbufpos >= scanbufsize) { + rd = read(h->qh_fd, scanbuf, sizeof(scanbuf)); + if (rd < 0 || rd % sizeof(struct v1_disk_dqblk)) + goto out_err; + if (!rd) + break; + scanbufpos = 0; + scanbufsize = rd / sizeof(struct v1_disk_dqblk); + } + ddqblk = ((struct v1_disk_dqblk *)scanbuf) + scanbufpos; + if ((ddqblk->dqb_ihardlimit | ddqblk->dqb_isoftlimit | + ddqblk->dqb_bhardlimit | ddqblk->dqb_bsoftlimit | + ddqblk->dqb_curblocks | ddqblk->dqb_curinodes | + ddqblk->dqb_itime | ddqblk->dqb_btime) == 0) continue; - v1_disk2memdqblk(&dquot->dq_dqb, &ddqblk); + v1_disk2memdqblk(&dquot->dq_dqb, ddqblk); dquot->dq_id = id; id2name(dquot->dq_id, h->qh_type, name); if ((rd = process_dquot(dquot, name)) < 0) { @@ -313,5 +325,6 @@ static int v1_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct d } if (!rd) /* EOF? */ return 0; +out_err: return -1; /* Some read errstr... */ } diff --git a/quotaio_v1.h b/quotaio_v1.h index a91a975..aa9448e 100644 --- a/quotaio_v1.h +++ b/quotaio_v1.h @@ -18,7 +18,7 @@ struct v1_disk_dqblk { u_int32_t dqb_bsoftlimit; /* preferred limit on disk blks */ u_int32_t dqb_curblocks; /* current block count */ u_int32_t dqb_ihardlimit; /* maximum # allocated inodes */ - u_int32_t dqb_isoftlimit; /* preferred limit on disk blks */ + u_int32_t dqb_isoftlimit; /* preferred limit on inodes */ u_int32_t dqb_curinodes; /* current # allocated inodes */ time_t dqb_btime; /* time limit for excessive disk use */ time_t dqb_itime; /* time limit for excessive files */ @@ -34,7 +34,7 @@ #ident "$Copyright: (c) 1980, 1990 Regents of the University of California $" #ident "$Copyright: All rights reserved. $" -#ident "$Id: quotaon.c,v 1.5 2001/05/15 09:28:49 jkar8572 Exp $" +#ident "$Id: quotaon.c,v 1.6 2001/08/15 20:13:42 jkar8572 Exp $" /* * Turn quota on/off for a filesystem. @@ -61,19 +61,6 @@ static void usage(void) } /* - * Check to see if target appears in list of size cnt. - */ -static int oneof(char *dir, char *dev, char *list[], int cnt) -{ - int i; - - for (i = 0; i < cnt; i++) - if (devcmp(dev, list[i]) || dircmp(dir, list[i])) - return (i); - return (-1); -} - -/* * For both VFS quota formats, need to pass in the quota file; * for XFS quota manager, pass on the -x command line option. */ @@ -110,9 +97,7 @@ static int newstate(struct mntent *mnt, int offmode, int type, char *extra) int main(int argc, char **argv) { - FILE *fp; struct mntent *mnt; - long argnum, done = 0; char *xarg = NULL; int c, offmode = 0, errs = 0; @@ -163,20 +148,12 @@ int main(int argc, char **argv) kqf = kern_quota_format(); - fp = setmntent(MNTTAB, "r"); - while ((mnt = getmntent(fp))) { - if (aflag) { - if (hasmntopt(mnt, MNTOPT_NOAUTO) || !strcmp(mnt->mnt_type, MNTTYPE_NFS)) - continue; - } - else { - if ((argnum = oneof(mnt->mnt_dir, mnt->mnt_fsname, argv, argc)) >= 0) - done |= 1 << argnum; - else - continue; - } + if (init_mounts_scan(aflag ? 0 : argc, argv) < 0) + return 1; + while ((mnt = get_next_mount())) { if (!strcmp(mnt->mnt_type, MNTTYPE_NFS)) { - fprintf(stderr, "%s: Quota can't be turned on on NFS filesystem\n", mnt->mnt_fsname); + if (!aflag) + fprintf(stderr, "%s: Quota can't be turned on on NFS filesystem\n", mnt->mnt_fsname); continue; } @@ -185,11 +162,8 @@ int main(int argc, char **argv) if (uflag) errs += newstate(mnt, offmode, USRQUOTA, xarg); } - endmntent(fp); + end_mounts_scan(); - for (c = 0; c < argc; c++) - if ((done & (1 << c)) == 0) - errstr(_("%s not found in fstab\n"), argv[c]); return errs; } diff --git a/quotaon_xfs.c b/quotaon_xfs.c index f9d1918..70e9e75 100644 --- a/quotaon_xfs.c +++ b/quotaon_xfs.c @@ -150,7 +150,7 @@ static int xfs_delete(char *dev, int type, int flags, int rootfs, int *xopts) return (check < 0); if (quotactl(QCMD(qcmd, type), dev, 0, (void *)xopts) < 0) { - errstr(_("Failed to delete quota: %s"), + errstr(_("Failed to delete quota: %s\n"), strerror(errno)); return 1; } @@ -211,6 +211,42 @@ void time2str(time_t seconds, char *buf, int flags) } /* + * Convert number in quota blocks to some nice short form for printing + */ +void space2str(qsize_t space, char *buf, int format) +{ + int i; + char suffix[8] = " MGT"; + + space = qb2kb(space); + if (format) + for (i = 3; i > 0; i--) + if (space >= (1LL << (QUOTABLOCK_BITS*i))*100) { + sprintf(buf, "%Lu%c", (space+(1 << (QUOTABLOCK_BITS*i))-1) >> (QUOTABLOCK_BITS*i), suffix[i]); + return; + } + sprintf(buf, "%Lu", space); +} + +/* + * Convert number to some nice short form for printing + */ +void number2str(unsigned long long num, char *buf, int format) +{ + int i; + unsigned long long div; + char suffix[8] = " kmgt"; + + if (format) + for (i = 4, div = 1000000000000LL; i > 0; i--, div /= 1000) + if (num >= 100*div) { + sprintf(buf, "%Lu%c", (num+div-1) / div, suffix[i]); + return; + } + sprintf(buf, "%Lu", num); +} + +/* * Check for XFS filesystem with quota accounting enabled */ static int hasxfsquota(struct mntent *mnt, int type) @@ -341,48 +377,31 @@ char *get_qf_name(struct mntent *mnt, int type, int fmt) struct quota_handle **create_handle_list(int count, char **mntpoints, int type, int fmt, int flags) { - FILE *mntf; struct mntent *mnt; - int i, gotmnt = 0; + int gotmnt = 0; static struct quota_handle *hlist[MAXMNTPOINTS]; - 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; - /* Do we already have this device? (filesystem may be mounted multiple times) */ - for (i = 0; i < gotmnt && !devcmp_handle(dev, hlist[i]); i++); - if (i < gotmnt) - continue; - for (i = 0; i < count; i++) - /* Is this the filesystem we want? */ - if (devcmp(dev, mntpoints[i]) || dircmp(mnt->mnt_dir, mntpoints[i])) - break; - free((char *)dev); - if (!count || i < count) { - if (strcmp(mnt->mnt_type, MNTTYPE_NFS)) { /* No NFS? */ - if (gotmnt == MAXMNTPOINTS) - die(3, _("Too many mountpoints. Please report to: %s\n"), - MY_EMAIL); - if (!(hlist[gotmnt] = init_io(mnt, type, fmt, flags))) - continue; - gotmnt++; - } - else if (!(flags & IOI_LOCALONLY) && (fmt == -1 || fmt == QF_RPC)) { /* Use NFS? */ + if (init_mounts_scan(count, mntpoints) < 0) + die(2, _("Can't initialize mountpoint scan.\n")); + while ((mnt = get_next_mount())) { + if (strcmp(mnt->mnt_type, MNTTYPE_NFS)) { /* No NFS? */ + if (gotmnt+1 == MAXMNTPOINTS) + die(2, _("Too many mountpoints with quota. Contact %s\n"), MY_EMAIL); + if (!(hlist[gotmnt] = init_io(mnt, type, fmt, flags))) + continue; + gotmnt++; + } + else if (!(flags & IOI_LOCALONLY) && (fmt == -1 || fmt == QF_RPC)) { /* Use NFS? */ #ifdef RPC - if (gotmnt == MAXMNTPOINTS) - die(3, _("Too many mountpoints. Please report to: %s\n"), - MY_EMAIL); - if (!(hlist[gotmnt] = init_io(mnt, type, fmt, flags))) - continue; - gotmnt++; + if (gotmnt+1 == MAXMNTPOINTS) + die(2, _("Too many mountpoints with quota. Contact %s\n"), MY_EMAIL); + if (!(hlist[gotmnt] = init_io(mnt, type, fmt, flags))) + continue; + gotmnt++; #endif - } } } - endmntent(mntf); + end_mounts_scan(); hlist[gotmnt] = NULL; if (count && gotmnt != count) die(1, _("Not all specified mountpoints are using quota.\n")); @@ -518,3 +537,251 @@ int kern_quota_on(const char *dev, int type, int fmt) return QF_VFSOLD; return -1; } + +/* + * + * mtab/fstab handling routines + * + */ + +struct mount_entry { + char *me_type; /* Type of filesystem for given entry */ + char *me_opts; /* Options of filesystem */ + dev_t me_dev; /* Device filesystem is mounted on */ + ino_t me_ino; /* Inode number of root of filesystem */ + const char *me_devname; /* Name of device (after pass through get_device_name()) */ + const char *me_dir; /* One of mountpoints of filesystem */ +}; + +struct searched_dir { + int sd_dir; /* Is searched dir mountpoint or in fact device? */ + dev_t sd_dev; /* Device mountpoint lies on */ + ino_t sd_ino; /* Inode number of mountpoint */ + const char *sd_name; /* Name of given dir/device */ +}; + +#define ALLOC_ENTRIES_NUM 16 /* Allocate entries by this number */ + +static int mnt_entries_cnt; /* Number of cached mountpoint entries */ +static struct mount_entry *mnt_entries; /* Cached mounted filesystems */ +static int check_dirs_cnt, act_checked; /* Number of dirs to check; Actual checked dir/(mountpoint in case of -a) */ +static struct searched_dir *check_dirs; /* Directories to check */ + +/* Cache mtab/fstab */ +static int cache_mnt_table(void) +{ + FILE *mntf; + struct mntent *mnt; + struct stat st; + int allocated = 0, i; + dev_t dev; + char mntpointbuf[PATH_MAX]; + + if (!(mntf = setmntent(_PATH_MOUNTED, "r"))) { + if (errno != ENOENT) { + errstr(_("Can't open %s: %s\n"), _PATH_MOUNTED, strerror(errno)); + return -1; + } + else /* Fallback on fstab when mtab not available */ + if (!(mntf = setmntent(_PATH_MNTTAB, "r"))) { + errstr(_("Can't open %s: %s\n"), _PATH_MNTTAB, strerror(errno)); + return -1; + } + } + mnt_entries = smalloc(sizeof(struct mount_entry) * ALLOC_ENTRIES_NUM); + allocated += ALLOC_ENTRIES_NUM; + while ((mnt = getmntent(mntf))) { + const char *devname; + + if (!CORRECT_FSTYPE(mnt->mnt_type)) /* Just basic filtering */ + continue; + if (!(devname = get_device_name(mnt->mnt_fsname))) { + errstr(_("Can't get device name for %s\n"), mnt->mnt_fsname); + continue; + } + if (!realpath(mnt->mnt_dir, mntpointbuf)) { + errstr(_("Can't resolve mountpoint path %s: %s\n"), mnt->mnt_dir, strerror(errno)); + free((char *)devname); + continue; + } + if (strcmp(mnt->mnt_type, MNTTYPE_NFS)) { + if (stat(devname, &st) < 0) { /* Can't stat mounted device? */ + errstr(_("Can't stat() mounted device %s: %s\n"), devname, strerror(errno)); + free((char *)devname); + continue; + } + if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) + errstr(_("Warning: Device %s is not block nor character device.\n"), devname); + dev = st.st_rdev; + for (i = 0; i < mnt_entries_cnt && mnt_entries[i].me_dev != dev; i++); + } + else { /* Cope with network filesystems */ + dev = 0; + for (i = 0; i < mnt_entries_cnt && strcmp(mnt_entries[i].me_devname, devname); i++); + } + if (i == mnt_entries_cnt) { /* New mounted device? */ + if (stat(mnt->mnt_dir, &st) < 0) { /* Can't stat mountpoint? We have better ignore it... */ + errstr(_("Can't stat() mountpoint %s: %s\n"), mnt->mnt_dir, strerror(errno)); + free((char *)devname); + continue; + } + if (allocated == mnt_entries_cnt) { + allocated += ALLOC_ENTRIES_NUM; + mnt_entries = srealloc(mnt_entries, allocated * sizeof(struct mount_entry)); + } + mnt_entries[i].me_type = sstrdup(mnt->mnt_type); + mnt_entries[i].me_opts = sstrdup(mnt->mnt_opts); + mnt_entries[i].me_dev = dev; + mnt_entries[i].me_ino = st.st_ino; + mnt_entries[i].me_devname = devname; + mnt_entries[i].me_dir = sstrdup(mntpointbuf); + mnt_entries_cnt++; + } + else + free((char *)devname); /* We don't need it any more */ + } + endmntent(mntf); + return 0; +} + +/* Process and store given paths */ +static int process_dirs(int dcnt, char **dirs) +{ + struct stat st; + int i; + char mntpointbuf[PATH_MAX]; + + check_dirs_cnt = 0; + act_checked = -1; + if (dcnt) { + check_dirs = smalloc(sizeof(struct searched_dir) * dcnt); + for (i = 0; i < dcnt; i++) { + if (stat(dirs[i], &st) < 0) { + errstr(_("Can't stat() given mountpoint %s: %s\n"), dirs[i], strerror(errno)); + continue; + } + check_dirs[check_dirs_cnt].sd_dir = S_ISDIR(st.st_mode); + if (S_ISDIR(st.st_mode)) { + check_dirs[check_dirs_cnt].sd_dev = st.st_dev; + check_dirs[check_dirs_cnt].sd_ino = st.st_ino; + } + else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) + check_dirs[check_dirs_cnt].sd_dev = st.st_rdev; + else { + errstr(_("Specified path %s is not directory nor device.\n"), dirs[i]); + continue; + } + if (!realpath(dirs[i], mntpointbuf)) { + errstr(_("Can't resolve path %s: %s\n"), dirs[i], strerror(errno)); + continue; + } + check_dirs[check_dirs_cnt].sd_name = sstrdup(mntpointbuf); + check_dirs_cnt++; + } + } + return 0; +} + +/* + * Initialize mountpoint scan + */ +int init_mounts_scan(int dcnt, char **dirs) +{ + if (cache_mnt_table() < 0) + return -1; + return process_dirs(dcnt, dirs); +} + +/* Find next usable mountpoint when scanning all mountpoints */ +static int find_next_entry_all(int *pos) +{ + struct mntent mnt; + +restart: + if (++act_checked == mnt_entries_cnt) + return 0; + mnt.mnt_fsname = (char *)mnt_entries[act_checked].me_devname; + mnt.mnt_type = mnt_entries[act_checked].me_type; + mnt.mnt_opts = mnt_entries[act_checked].me_opts; + mnt.mnt_dir = (char *)mnt_entries[act_checked].me_dir; + if (hasmntopt(&mnt, MNTOPT_NOAUTO)) + goto restart; + *pos = act_checked; + return 1; +} + +/* Find next usable mountpoint when scanning selected mountpoints */ +static int find_next_entry_sel(int *pos) +{ + int i; + struct searched_dir *sd; + +restart: + if (++act_checked == check_dirs_cnt) + return 0; + sd = check_dirs + act_checked; + for (i = 0; i < mnt_entries_cnt; i++) { + if (sd->sd_dir) { + if (sd->sd_dev == mnt_entries[i].me_dev && sd->sd_ino == mnt_entries[i].me_ino) + break; + } + else + if (sd->sd_dev == mnt_entries[i].me_dev) + break; + } + if (i == mnt_entries_cnt) { + errstr(_("Mountpoint (or device) %s not found.\n"), sd->sd_name); + goto restart; + } + *pos = i; + return 1; +} + +/* + * Return next directory from the list + */ +struct mntent *get_next_mount(void) +{ + static struct mntent mnt; + int mntpos; + + if (!check_dirs_cnt) { /* Scan all mountpoints? */ + if (!find_next_entry_all(&mntpos)) + return NULL; + mnt.mnt_dir = (char *)mnt_entries[mntpos].me_dir; + } + else { + if (!find_next_entry_sel(&mntpos)) + return NULL; + mnt.mnt_dir = (char *)check_dirs[act_checked].sd_name; + } + mnt.mnt_fsname = (char *)mnt_entries[mntpos].me_devname; + mnt.mnt_type = mnt_entries[mntpos].me_type; + mnt.mnt_opts = mnt_entries[mntpos].me_opts; + return &mnt; +} + +/* + * Free all structures allocated for mountpoint scan + */ +void end_mounts_scan(void) +{ + int i; + + for (i = 0; i < mnt_entries_cnt; i++) { + free(mnt_entries[i].me_type); + free(mnt_entries[i].me_opts); + free((char *)mnt_entries[i].me_devname); + free((char *)mnt_entries[i].me_dir); + } + free(mnt_entries); + mnt_entries = NULL; + mnt_entries_cnt = 0; + if (check_dirs_cnt) { + for (i = 0; i < check_dirs_cnt; i++) + free((char *)check_dirs[i].sd_name); + free(check_dirs); + } + check_dirs = NULL; + check_dirs_cnt = 0; +} @@ -9,10 +9,12 @@ #include <sys/types.h> #include "mntopt.h" +#include "quota.h" #define MAXNAMELEN 64 /* Maximal length of user/group name */ #define MAXTIMELEN 40 /* Maximal length of time string */ -#define MAXMNTPOINTS 128 /* Maximal number of processed mountpoints per one run */ +#define MAXNUMLEN 32 /* Maximal length of number */ +#define MAXMNTPOINTS 128 /* Maximal number of mountpoints with quota */ /* Flags for formatting time */ #define TF_ROUND 0x1 /* Should be printed time rounded? */ @@ -58,6 +60,12 @@ void difftime2str(time_t, char *); /* Convert time to printable form */ void time2str(time_t, char *, int); +/* Convert number in quota blocks to short printable form */ +void space2str(qsize_t, char *, int); + +/* Convert number to short printable form */ +void number2str(unsigned long long, char *, int); + /* Check to see if particular quota is to be enabled */ int hasquota(struct mntent *mnt, int type); @@ -85,4 +93,13 @@ int kern_quota_format(void); /* Check whether is quota turned on on given device for given type */ int kern_quota_on(const char *dev, int type, int fmt); +/* Initialize mountpoints scan */ +int init_mounts_scan(int dcnt, char **dirs); + +/* Return next mountpoint for scan */ +struct mntent *get_next_mount(void); + +/* Free all structures associated with mountpoints scan */ +void end_mounts_scan(void); + #endif /* _QUOTASYS_H */ @@ -5,7 +5,7 @@ repquota \- summarize quotas for a filesystem .SH SYNOPSIS .B /usr/sbin/repquota [ -.B \-vtug +.B \-vtsug ] [ .B \-F .I format-name @@ -14,7 +14,7 @@ repquota \- summarize quotas for a filesystem .LP .B /usr/sbin/repquota [ -.B \-avtug +.B \-avtsug ] [ .B \-F .I format-name @@ -49,6 +49,10 @@ information. Truncate user/group names longer than 9 characters. This results in nicer output when there are such names. .TP +.B \-s +Try to report used space, number of used inodes and limits in more appropriate units +than default ones. +.TP .B \-F \f2format-name\f1 Report quota for specified format (ie. don't perform format autodetection). Possible format names are: @@ -26,6 +26,7 @@ #define FL_VERBOSE 4 #define FL_ALL 8 #define FL_TRUNCNAMES 16 +#define FL_SHORTNUMS 32 int flags, fmt = -1; char **mnt; @@ -34,8 +35,8 @@ char *progname; static void usage(void) { - errstr(_("Utility for reporting quotas.\nUsage:\n%s [-vugt] [-F quotaformat] (-a | mntpoint)\n"), progname); - errstr(_("Bugs to %s\n"), MY_EMAIL); + errstr(_("Utility for reporting quotas.\nUsage:\n%s [-vugts] [-F quotaformat] (-a | mntpoint)\n"), progname); + fprintf(stderr, _("Bugs to %s\n"), MY_EMAIL); exit(1); } @@ -49,7 +50,7 @@ static void parse_options(int argcnt, char **argstr) else slash++; - while ((ret = getopt(argcnt, argstr, "VavughtF:")) != -1) { + while ((ret = getopt(argcnt, argstr, "VavughtsF:")) != -1) { switch (ret) { case '?': case 'h': @@ -72,6 +73,9 @@ static void parse_options(int argcnt, char **argstr) case 't': flags |= FL_TRUNCNAMES; break; + case 's': + flags |= FL_SHORTNUMS; + break; case 'F': if ((fmt = name2fmt(optarg)) == QF_ERROR) exit(1); @@ -107,6 +111,8 @@ static int print(struct dquot *dquot, char *name) { char pname[MAXNAMELEN]; char time[MAXTIMELEN]; + char numbuf[3][MAXNUMLEN]; + struct util_dqblk *entry = &dquot->dq_dqb; if (!entry->dqb_curspace && !entry->dqb_curinodes && !(flags & FL_VERBOSE)) @@ -115,16 +121,18 @@ static int print(struct dquot *dquot, char *name) if (flags & FL_TRUNCNAMES) pname[PRINTNAMELEN] = 0; difftime2str(entry->dqb_btime, time); - printf("%-*s %c%c%8Lu%8Lu%8Lu%7s", PRINTNAMELEN, pname, - overlim(qb2kb(toqb(entry->dqb_curspace)), qb2kb(entry->dqb_bsoftlimit), - qb2kb(entry->dqb_bhardlimit)), overlim(entry->dqb_curinodes, - entry->dqb_isoftlimit, - entry->dqb_ihardlimit), - (long long)qb2kb(toqb(entry->dqb_curspace)), (long long)qb2kb(entry->dqb_bsoftlimit), - (long long)qb2kb(entry->dqb_bhardlimit), time); + space2str(toqb(entry->dqb_curspace), numbuf[0], flags & FL_SHORTNUMS); + space2str(entry->dqb_bsoftlimit, numbuf[1], flags & FL_SHORTNUMS); + space2str(entry->dqb_bhardlimit, numbuf[2], flags & FL_SHORTNUMS); + printf("%-*s %c%c %7s %7s %7s %6s", PRINTNAMELEN, pname, + overlim(qb2kb(toqb(entry->dqb_curspace)), qb2kb(entry->dqb_bsoftlimit), qb2kb(entry->dqb_bhardlimit)), + overlim(entry->dqb_curinodes, entry->dqb_isoftlimit, entry->dqb_ihardlimit), + numbuf[0], numbuf[1], numbuf[2], time); difftime2str(entry->dqb_itime, time); - printf("%8Lu%6Lu%6Lu%7s\n", (long long)entry->dqb_curinodes, - (long long)entry->dqb_isoftlimit, (long long)entry->dqb_ihardlimit, time); + number2str(entry->dqb_curinodes, numbuf[0], flags & FL_SHORTNUMS); + number2str(entry->dqb_isoftlimit, numbuf[1], flags & FL_SHORTNUMS); + number2str(entry->dqb_ihardlimit, numbuf[2], flags & FL_SHORTNUMS); + printf(" %7s %5s %5s %6s\n", numbuf[0], numbuf[1], numbuf[2], time); return 0; } diff --git a/rquota_client.c b/rquota_client.c index 5efc920..553bc10 100644 --- a/rquota_client.c +++ b/rquota_client.c @@ -9,7 +9,7 @@ * * This part does the rpc-communication with the rquotad. * - * Version: $Id: rquota_client.c,v 1.3 2001/07/17 21:02:55 jkar8572 Exp $ + * Version: $Id: rquota_client.c,v 1.4 2001/08/15 20:13:42 jkar8572 Exp $ * * Author: Marco van Wieringen <mvw@planets.elm.net> * @@ -168,11 +168,12 @@ void rpc_rquota_get(struct dquot *dquot) */ auth_destroy(clnt->cl_auth); clnt_destroy(clnt); + puts("get2"); } else { result = NULL; } - + printf("result: %p, status: %d\n", result, result?result->status:0); if (result == NULL || !result->status) { if (dquot->dq_h->qh_type == USRQUOTA) { /* diff --git a/rquota_server.c b/rquota_server.c index 65d5dc2..c7b1a4c 100644 --- a/rquota_server.c +++ b/rquota_server.c @@ -9,7 +9,7 @@ * * This part does the lookup of the info. * - * Version: $Id: rquota_server.c,v 1.5 2001/07/17 21:02:55 jkar8572 Exp $ + * Version: $Id: rquota_server.c,v 1.6 2001/08/15 20:13:42 jkar8572 Exp $ * * Author: Marco van Wieringen <mvw@planets.elm.net> * @@ -127,9 +127,6 @@ setquota_rslt *setquotainfo(int flags, caddr_t * argp, struct svc_req *rqstp) setquota_args *args; ext_setquota_args *ext_args; } arguments; - struct stat st; - dev_t device; - FILE *mntf; struct util_dqblk dqblk; struct dquot *dquot; struct mntent *mnt; @@ -184,25 +181,19 @@ setquota_rslt *setquotainfo(int flags, caddr_t * argp, struct svc_req *rqstp) } result.status = Q_NOQUOTA; - if (stat(pathname, &st) == -1) - return (&result); - - device = st.st_dev; result.setquota_rslt_u.sqr_rquota.rq_bsize = RPC_DQBLK_SIZE; - mntf = setmntent(_PATH_MOUNTED, "r"); - while ((mnt = getmntent(mntf))) { - if (stat(mnt->mnt_dir, &st) == -1) - continue; - if (st.st_dev != device) - continue; - if (!(handles[0] = init_io(mnt, type, -1, 0))) - continue; - break; + if (init_mounts_scan(1, &pathname) < 0) + goto out; + if (!(mnt = get_next_mount())) { + end_mounts_scan(); + goto out; } - endmntent(mntf); - if (!handles[0]) + if (!(handles[0] = init_io(mnt, type, -1, 0))) { + end_mounts_scan(); goto out; + } + end_mounts_scan(); if (!(dquot = handles[0]->qh_ops->read_dquot(handles[0], id))) goto out; if (qcmd == QCMD(Q_RPC_SETQLIM, type) || qcmd == QCMD(Q_RPC_SETQUOTA, type)) { @@ -220,7 +211,7 @@ setquota_rslt *setquotainfo(int flags, caddr_t * argp, struct svc_req *rqstp) if (handles[0]->qh_ops->commit_dquot(dquot) == -1) goto out; result.status = Q_OK; - out: +out: dispose_handle_list(handles); #else result.status = Q_EPERM; @@ -235,9 +226,6 @@ getquota_rslt *getquotainfo(int flags, caddr_t * argp, struct svc_req * rqstp) getquota_args *args; ext_getquota_args *ext_args; } arguments; - struct stat st; - dev_t device; - FILE *mntf; struct dquot *dquot = NULL; struct mntent *mnt; char *pathname; @@ -289,26 +277,21 @@ getquota_rslt *getquotainfo(int flags, caddr_t * argp, struct svc_req * rqstp) } result.status = Q_NOQUOTA; - - if (stat(pathname, &st) == -1) - return (&result); - - device = st.st_dev; result.getquota_rslt_u.gqr_rquota.rq_bsize = RPC_DQBLK_SIZE; - mntf = setmntent(_PATH_MOUNTED, "r"); - while ((mnt = getmntent(mntf))) { - if (stat(mnt->mnt_dir, &st) == -1) - continue; - if (st.st_dev != device) - continue; - if (!(handles[0] = init_io(mnt, type, -1, IOI_READONLY))) - continue; - break; + if (init_mounts_scan(1, &pathname) < 0) + goto out; + if (!(mnt = get_next_mount())) { + end_mounts_scan(); + goto out; } - endmntent(mntf); - if (!handles[0]) + printf("dev: %s dir: %s\n", mnt->mnt_fsname, mnt->mnt_dir); + if (!(handles[0] = init_io(mnt, type, -1, IOI_READONLY))) { + end_mounts_scan(); goto out; + } + printf("Returned: %p\n", handles[0]); + end_mounts_scan(); if (!(flags & ACTIVE) || QIO_ENABLED(handles[0])) dquot = handles[0]->qh_ops->read_dquot(handles[0], id); if (dquot) { @@ -319,6 +302,7 @@ getquota_rslt *getquotainfo(int flags, caddr_t * argp, struct svc_req * rqstp) } out: dispose_handle_list(handles); + printf("state: %d\n", result.status); return (&result); } diff --git a/rquota_svc.c b/rquota_svc.c index 6baf0a3..90734e9 100644 --- a/rquota_svc.c +++ b/rquota_svc.c @@ -10,7 +10,7 @@ * * Author: Marco van Wieringen <mvw@planets.elm.net> * - * Version: $Id: rquota_svc.c,v 1.2 2001/05/02 09:32:22 jkar8572 Exp $ + * Version: $Id: rquota_svc.c,v 1.3 2001/08/15 20:13:42 jkar8572 Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -118,7 +118,7 @@ static void rquotaprog_1(struct svc_req *rqstp, register SVCXPRT * transp) svcerr_systemerr(transp); } if (!svc_freeargs(transp, xdr_argument, (caddr_t) & argument)) { - errstr(_("unable to free arguments")); + errstr(_("unable to free arguments\n")); exit(1); } return; @@ -196,7 +196,7 @@ static void rquotaprog_2(struct svc_req *rqstp, register SVCXPRT * transp) svcerr_systemerr(transp); } if (!svc_freeargs(transp, xdr_argument, (caddr_t) & argument)) { - errstr(_("unable to free arguments")); + errstr(_("unable to free arguments\n")); exit(1); } return; @@ -219,35 +219,35 @@ int main(int argc, char **argv) transp = svcudp_create(RPC_ANYSOCK); if (transp == NULL) { - errstr(_("cannot create udp service.")); + errstr(_("cannot create udp service.\n")); exit(1); } if (!svc_register(transp, RQUOTAPROG, RQUOTAVERS, rquotaprog_1, IPPROTO_UDP)) { - errstr(_("unable to register (RQUOTAPROG, RQUOTAVERS, udp).")); + errstr(_("unable to register (RQUOTAPROG, RQUOTAVERS, udp).\n")); exit(1); } if (!svc_register(transp, RQUOTAPROG, EXT_RQUOTAVERS, rquotaprog_2, IPPROTO_UDP)) { - errstr(_("unable to register (RQUOTAPROG, EXT_RQUOTAVERS, udp).")); + errstr(_("unable to register (RQUOTAPROG, EXT_RQUOTAVERS, udp).\n")); exit(1); } transp = svctcp_create(RPC_ANYSOCK, 0, 0); if (transp == NULL) { - errstr(_("cannot create tcp service.")); + errstr(_("cannot create tcp service.\n")); exit(1); } if (!svc_register(transp, RQUOTAPROG, RQUOTAVERS, rquotaprog_1, IPPROTO_TCP)) { - errstr(_("unable to register (RQUOTAPROG, RQUOTAVERS, tcp).")); + errstr(_("unable to register (RQUOTAPROG, RQUOTAVERS, tcp).\n")); exit(1); } if (!svc_register(transp, RQUOTAPROG, EXT_RQUOTAVERS, rquotaprog_2, IPPROTO_TCP)) { - errstr(_("unable to register (RQUOTAPROG, EXT_RQUOTAVERS, tcp).")); + errstr(_("unable to register (RQUOTAPROG, EXT_RQUOTAVERS, tcp).\n")); exit(1); } daemon(1, 1); svc_run(); - errstr(_("svc_run returned")); + errstr(_("svc_run returned\n")); exit(1); /* NOTREACHED */ } @@ -50,7 +50,7 @@ static void usage(void) " setquota [-u|-g] [-F quotaformat] <-p protouser|protogroup> <user|group> -a|<filesystem>...\n" " setquota [-u|-g] [-F quotaformat] -t <blockgrace> <inodegrace> -a|<filesystem>...\n")); #endif - errstr(_("Bugs to: %s\n"), MY_EMAIL); + fprintf(stderr, _("Bugs to: %s\n"), MY_EMAIL); exit(1); } |