summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjkar8572 <jkar8572>2001-04-11 10:12:36 +0000
committerjkar8572 <jkar8572>2001-04-11 10:12:36 +0000
commitbc47c58ac28bea3666ae128f9493f58195baee64 (patch)
tree73bf190dfc0daa5a7a6d8dadabc6b8b337396ade
parent7ec003b82d056fa150924f15da0d0d0e353cf041 (diff)
downloadlinuxquota-bc47c58ac28bea3666ae128f9493f58195baee64.tar.gz
Updated manpages.
Fixed small bug in repquota (User vs Group). Some XFS updates. Fixed problems with devfs and relative paths.
-rw-r--r--Makefile.in3
-rw-r--r--common.c29
-rw-r--r--common.h6
-rw-r--r--convertquota.c2
-rw-r--r--edquota.82
-rw-r--r--edquota.c4
-rw-r--r--quot.821
-rw-r--r--quot.c210
-rw-r--r--quot.h16
-rw-r--r--quotacheck.c6
-rw-r--r--quotaio.c2
-rw-r--r--quotaio.h2
-rw-r--r--quotaio_xfs.c14
-rw-r--r--quotaon.c9
-rw-r--r--quotaops.c6
-rw-r--r--quotasys.c36
-rw-r--r--quotasys.h6
-rw-r--r--repquota.c6
-rw-r--r--setquota.859
19 files changed, 298 insertions, 141 deletions
diff --git a/Makefile.in b/Makefile.in
index 7033965..3f7772f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -78,7 +78,8 @@ install: all inst_mo
$(LN) quotaon $(ROOTDIR)$(root_sbindir)/quotaoff
chown -h $(BIN_OWNER):$(BIN_GROUP) $(ROOTDIR)$(root_sbindir)/quotaoff
-$(INSTALL) -m $(DEF_SBIN_MODE) \
- edquota repquota warnquota quotastats setquota quot $(ROOTDIR)$(sbindir)
+ edquota repquota warnquota quotastats setquota quot xqmstats \
+ $(ROOTDIR)$(sbindir)
-$(INSTALL) -m 755 -d $(ROOTDIR)$(includedir)/rpcsvc
-$(INSTALL) -m 644 rquota.h rquota.x $(ROOTDIR)$(includedir)/rpcsvc
-$(INSTALL) -s -m $(DEF_SBIN_MODE) quota $(ROOTDIR)$(bindir)
diff --git a/common.c b/common.c
index 754c7ac..96f1747 100644
--- a/common.c
+++ b/common.c
@@ -11,6 +11,7 @@
#include <string.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include "pot.h"
#include "common.h"
@@ -59,6 +60,34 @@ 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);
diff --git a/common.h b/common.h
index 58119a6..3b779a5 100644
--- a/common.h
+++ b/common.h
@@ -24,6 +24,12 @@ 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 73696d8..5422081 100644
--- a/convertquota.c
+++ b/convertquota.c
@@ -98,7 +98,7 @@ void convert_file(int type)
while ((mnt = getmntent(mntf))) {
if (!(dev = get_device_name(mnt->mnt_fsname)))
continue;
- if (!strcmp(dev, mntpoint) || !strcmp(mnt->mnt_dir, mntpoint))
+ if (devcmp(dev, mntpoint) || dircmp(mnt->mnt_dir, mntpoint))
break;
}
if (!mnt)
diff --git a/edquota.8 b/edquota.8
index 69f56d1..6b1085c 100644
--- a/edquota.8
+++ b/edquota.8
@@ -39,7 +39,7 @@ Users are permitted to exceed their soft limits for a grace period that
may be specified per filesystem. Once the grace period has expired, the
soft limit is enforced as a hard limit.
.PP
-The current usage information in the file is for imformational purposes;
+The current usage information in the file is for informational purposes;
only the hard and soft limits can be changed.
.PP
Upon leaving the editor,
diff --git a/edquota.c b/edquota.c
index 7817750..1910e7f 100644
--- a/edquota.c
+++ b/edquota.c
@@ -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.1 2001/03/23 12:03:26 jkar8572 Exp $"
+#ident "$Id: edquota.c,v 1.2 2001/04/11 10:12:36 jkar8572 Exp $"
/*
* Disk quota editor.
@@ -153,7 +153,7 @@ int main(int argc, char **argv)
for (pprivs = protoprivs, cprivs = curprivs; pprivs && cprivs;
pprivs = pprivs->dq_next, cprivs = cprivs->dq_next) {
- if (strcmp(pprivs->dq_h->qh_quotadev, cprivs->dq_h->qh_quotadev))
+ if (!devcmp_handles(pprivs->dq_h, cprivs->dq_h))
fprintf(stderr, _("fsname mismatch\n"));
else {
cprivs->dq_dqb.dqb_bsoftlimit =
diff --git a/quot.8 b/quot.8
index f72973d..5b96267 100644
--- a/quot.8
+++ b/quot.8
@@ -3,18 +3,18 @@
quot \- summarize filesystem ownership
.SH SYNOPSIS
.nf
-\f3quot\f1 [ \f3\-acfv\f1 ] [ filesystem... ]
+\f3quot\f1 [ \f3\-acfguv\f1 ] [ filesystem... ]
.fi
.SH DESCRIPTION
.IR quot
displays the number of kilobytes in the named
.I filesystem
-currently owned by each user.
+currently owned by each user or group.
.SH OPTIONS
.TP
.B \-a
Generate a report for all mounted filesystems giving the number of
-kilobytes used by each user.
+kilobytes used by each user or group.
.TP
.B \-c
Display three columns giving file size in kilobytes, number of
@@ -24,7 +24,13 @@ The last row is used as an overflow
bucket and is the total of all files greater than 500 kilobytes.
.TP
.B \-f
-Display count of kilobytes and number of files owned by each user.
+Display count of kilobytes and number of files owned by each user or group.
+.TP
+.B \-g
+Report on groups.
+.TP
+.B \-u
+Report on users (the default).
.TP
.B \-v
Display three columns containing the number of kilobytes not accessed in
@@ -33,10 +39,13 @@ the last 30, 60, and 90 days.
.PD 0
.TP 20
/etc/mtab
-mounted filesystems
+mounted filesystem table
.TP
/etc/passwd
-to get user names
+default set of users
+.TP
+/etc/group
+default set of groups
.PD
.SH "SEE ALSO"
du(1),
diff --git a/quot.c b/quot.c
index 162511d..fff2812 100644
--- a/quot.c
+++ b/quot.c
@@ -48,6 +48,7 @@
#include <time.h>
#include <utmp.h>
#include <pwd.h>
+#include <grp.h>
#include "pot.h"
#include "quot.h"
@@ -59,20 +60,23 @@
__uint64_t sizes[TSIZE];
__uint64_t overflow;
-static int fflag;
+static int aflag;
static int cflag;
+static int fflag;
+static int gflag;
+static int uflag;
static int vflag;
-static int aflag;
static char *progname;
static time_t now;
static void mounttable(char *);
-static char *username(uid_t);
-static void report(void);
+static char *idname(__uint32_t, int);
+static void report(const char *, char *, int);
+static void creport(const char *, char *);
static void usage(void)
{
- fprintf(stderr, _("Usage: %s [-acfvV] [filesystem...]\n"), progname);
+ fprintf(stderr, _("Usage: %s [-acfugvV] [filesystem...]\n"), progname);
exit(1);
}
@@ -83,7 +87,7 @@ int main(int argc, char **argv)
now = time(0);
progname = basename(argv[0]);
- while ((c = getopt(argc, argv, "acfvV")) != EOF) {
+ while ((c = getopt(argc, argv, "acfguvV")) != EOF) {
switch (c) {
case 'a':
aflag++;
@@ -94,6 +98,12 @@ int main(int argc, char **argv)
case 'f':
fflag++;
break;
+ case 'g':
+ gflag++;
+ break;
+ case 'u':
+ uflag++;
+ break;
case 'v':
vflag++;
break;
@@ -106,6 +116,8 @@ int main(int argc, char **argv)
}
if ((aflag && optind != argc) || (!aflag && optind == argc))
usage();
+ if (!uflag && !gflag)
+ uflag++;
if (aflag)
mounttable(NULL);
else {
@@ -129,8 +141,7 @@ static void mounttable(char *entry)
while ((mntp = getmntent(mtab)) != NULL) {
doit = 0;
dev = get_device_name(mntp->mnt_fsname);
- if ((entry != NULL) &&
- (strcmp(entry, mntp->mnt_dir) != 0) && (strcmp(entry, dev) != 0)) {
+ if (entry && !dircmp(mntp->mnt_dir, entry) && !devcmp(dev, entry)) {
free((char *)dev);
continue;
}
@@ -141,10 +152,13 @@ static void mounttable(char *entry)
doit = 1;
}
/* ...additional filesystems types here. */
- free((char *)dev);
- if (doit)
- report();
+ 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;
@@ -161,31 +175,34 @@ static int qcmp(du_t * p1, du_t * p2)
return -1;
if (p1->blocks < p2->blocks)
return 1;
- if (p1->uid > p2->uid)
+ if (p1->id > p2->id)
return 1;
- else if (p1->uid < p2->uid)
+ else if (p1->id < p2->id)
return -1;
return 0;
}
-static void report(void)
+static void creport(const char *file, char *fsdir)
{
int i;
+ __uint64_t t = 0;
+
+ printf(_("%s (%s):\n"), file, fsdir);
+ for (i = 0; i < TSIZE - 1; i++)
+ if (sizes[i] > 0) {
+ t += sizes[i] * i;
+ printf(_("%d\t%llu\t%llu\n"), i, sizes[i], t);
+ }
+ printf(_("%d\t%llu\t%llu\n"), TSIZE - 1, sizes[TSIZE - 1], overflow + t);
+}
+
+static void report(const char *file, char *fsdir, int type)
+{
du_t *dp;
- if (cflag) {
- __uint64_t t = 0;
-
- for (i = 0; i < TSIZE - 1; i++)
- if (sizes[i] > 0) {
- t += sizes[i] * i;
- printf(_("%d\t%llu\t%llu\n"), i, sizes[i], t);
- }
- printf(_("%d\t%llu\t%llu\n"), TSIZE - 1, sizes[TSIZE - 1], overflow + t);
- return;
- }
- qsort(du, ndu, sizeof(du[0]), (int (*)(const void *, const void *))qcmp);
- for (dp = du; dp < &du[ndu]; dp++) {
+ printf(_("%s (%s) %s:\n"), file, fsdir, type? "groups" : "users");
+ qsort(du[type], ndu[type], sizeof(du[type][0]), (int (*)(const void *, const void *))qcmp);
+ for (dp = du[type]; dp < &du[type][ndu[type]]; dp++) {
char *cp;
if (dp->blocks == 0)
@@ -193,10 +210,10 @@ static void report(void)
printf(_("%8llu "), dp->blocks);
if (fflag)
printf(_("%8llu "), dp->nfiles);
- if ((cp = username(dp->uid)) != NULL)
+ if ((cp = idname(dp->id, type)) != NULL)
printf(_("%-8.8s"), cp);
else
- printf(_("#%-7d"), dp->uid);
+ printf(_("#%-7d"), dp->id);
if (vflag)
printf(_(" %8llu %8llu %8llu"),
dp->blocks30, dp->blocks60, dp->blocks90);
@@ -204,45 +221,62 @@ static void report(void)
}
}
-static char *username(uid_t uid)
+static idcache_t *getnextent(int type, __uint32_t id, int byid)
{
- register struct passwd *pw;
- register uidcache_t *ncp;
- static uidcache_t nc[NUID];
- static int entriesleft = NUID;
+ struct passwd *pw;
+ struct group *gr;
+ static idcache_t idc;
+
+ if (type) { /* /etc/group */
+ if ((gr = byid? getgrgid(id) : getgrent()) == NULL)
+ return NULL;
+ idc.id = gr->gr_gid;
+ strncpy(idc.name, gr->gr_name, UT_NAMESIZE);
+ return &idc;
+ }
+ /* /etc/passwd */
+ if ((pw = byid? getpwuid(id) : getpwent()) == NULL)
+ return NULL;
+ idc.id = pw->pw_uid;
+ strncpy(idc.name, pw->pw_name, UT_NAMESIZE);
+ return &idc;
+}
+
+static char *idname(__uint32_t id, int type)
+{
+ idcache_t *ncp, *idp;
+ static idcache_t nc[2][NID];
+ static int entriesleft[2] = { NID, NID };
/* check cache for name first */
- ncp = &nc[uid & UIDMASK];
- if (ncp->uid == uid && ncp->name[0])
+ ncp = &nc[type][id & IDMASK];
+ if (ncp->id == id && ncp->name[0])
return ncp->name;
- if (entriesleft) {
+ if (entriesleft[type]) {
/*
- * If we haven't gone through the passwd file then
- * fill the cache while seaching for name.
- * This lets us run through passwd serially.
+ * If we haven't gone through the passwd/group file
+ * then fill the cache while seaching for name.
+ * This lets us run through passwd/group serially.
*/
- if (entriesleft == NUID)
- setpwent();
- while (((pw = getpwent()) != NULL) && entriesleft) {
- entriesleft--;
- ncp = &nc[pw->pw_uid & UIDMASK];
- if (ncp->name[0] == '\0' || pw->pw_uid == uid) {
- strncpy(ncp->name, pw->pw_name, UT_NAMESIZE);
- ncp->uid = uid;
- }
- if (pw->pw_uid == uid)
+ if (entriesleft[type] == NID)
+ type? setgrent() : setpwent();
+ while (((idp = getnextent(type, id, 0)) != NULL) && entriesleft[type]) {
+ entriesleft[type]--;
+ ncp = &nc[type][idp->id & IDMASK];
+ if (ncp->name[0] == '\0' || idp->id == id)
+ memcpy(ncp, idp, sizeof(idcache_t));
+ if (idp->id == id)
return ncp->name;
}
- endpwent();
- entriesleft = 0;
- ncp = &nc[uid & UIDMASK];
+ type? endgrent() : endpwent();
+ entriesleft[type] = 0;
+ ncp = &nc[type][id & IDMASK];
}
/* Not cached - do it the slow way & insert into cache */
- if ((pw = getpwuid(uid)) == NULL)
+ if ((idp = getnextent(type, id, 1)) == NULL)
return NULL;
- strncpy(ncp->name, pw->pw_name, UT_NAMESIZE);
- ncp->uid = uid;
+ memcpy(ncp, idp, sizeof(idcache_t));
return ncp->name;
}
@@ -250,11 +284,12 @@ static char *username(uid_t uid)
* === XFS specific code follows ===
*/
-static void acctXFS(xfs_bstat_t * p)
+static void acctXFS(xfs_bstat_t *p)
{
register du_t *dp;
du_t **hp;
__uint64_t size;
+ __uint32_t i, id;
if ((p->bs_mode & S_IFMT) == 0)
return;
@@ -270,32 +305,35 @@ static void acctXFS(xfs_bstat_t * p)
sizes[(int)size]++;
return;
}
- hp = &duhash[p->bs_uid % DUHASH];
- for (dp = *hp; dp; dp = dp->next)
- if (dp->uid == p->bs_uid)
- break;
- if (dp == 0) {
- if (ndu >= NDU)
- return;
- dp = &du[ndu++];
- dp->next = *hp;
- *hp = dp;
- dp->uid = p->bs_uid;
- dp->nfiles = 0;
- dp->blocks = 0;
- dp->blocks30 = 0;
- dp->blocks60 = 0;
- dp->blocks90 = 0;
+ for (i = 0; i < 2; i++) {
+ id = (i == 0)? p->bs_uid : p->bs_gid;
+ hp = &duhash[i][id % DUHASH];
+ for (dp = *hp; dp; dp = dp->next)
+ if (dp->id == id)
+ break;
+ if (dp == 0) {
+ if (ndu[i] >= NDU)
+ return;
+ dp = &du[i][(ndu[i]++)];
+ dp->next = *hp;
+ *hp = dp;
+ dp->id = id;
+ dp->nfiles = 0;
+ dp->blocks = 0;
+ dp->blocks30 = 0;
+ dp->blocks60 = 0;
+ dp->blocks90 = 0;
+ }
+ dp->blocks += size;
+
+ if (now - p->bs_atime.tv_sec > 30 * SEC24HR)
+ dp->blocks30 += size;
+ if (now - p->bs_atime.tv_sec > 60 * SEC24HR)
+ dp->blocks60 += size;
+ if (now - p->bs_atime.tv_sec > 90 * SEC24HR)
+ dp->blocks90 += size;
+ dp->nfiles++;
}
- dp->blocks += size;
-
- if (now - p->bs_atime.tv_sec > 30 * SEC24HR)
- dp->blocks30 += size;
- if (now - p->bs_atime.tv_sec > 60 * SEC24HR)
- dp->blocks60 += size;
- if (now - p->bs_atime.tv_sec > 90 * SEC24HR)
- dp->blocks90 += size;
- dp->nfiles++;
}
static void checkXFS(const char *file, char *fsdir)
@@ -316,16 +354,16 @@ static void checkXFS(const char *file, char *fsdir)
for (sts = 0; sts < TSIZE; sts++)
sizes[sts] = 0;
overflow = 0;
- for (dp = duhash; dp < &duhash[DUHASH]; dp++)
- *dp = 0;
- ndu = 0;
+ for (i = 0; i < 2; i++)
+ for (dp = duhash[i]; dp < &duhash[i][DUHASH]; dp++)
+ *dp = 0;
+ ndu[0] = ndu[1] = 0;
fsfd = open(fsdir, O_RDONLY);
if (fsfd < 0) {
fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, fsdir, strerror(errno));
exit(1);
}
- printf(_("%s (%s):\n"), file, fsdir);
sync();
buf = (xfs_bstat_t *) smalloc(NBSTAT * sizeof(xfs_bstat_t));
diff --git a/quot.h b/quot.h
index 2ba44fc..a77a3f1 100644
--- a/quot.h
+++ b/quot.h
@@ -35,9 +35,9 @@
#define SEC24HR (60*60*24) /* seconds per day */
typedef struct {
- uid_t uid;
+ __uint32_t id;
char name[UT_NAMESIZE + 1];
-} uidcache_t;
+} idcache_t;
typedef struct du {
struct du *next;
@@ -46,17 +46,17 @@ typedef struct du {
__uint64_t blocks60;
__uint64_t blocks90;
__uint64_t nfiles;
- uid_t uid;
+ __uint32_t id;
} du_t;
#define NDU 60000
#define DUHASH 8209
-static du_t du[NDU];
-static du_t *duhash[DUHASH];
-static int ndu;
+static du_t du[2][NDU];
+static du_t *duhash[2][DUHASH];
+static int ndu[2];
-#define NUID 256
-#define UIDMASK (NUID-1)
+#define NID 256
+#define IDMASK (NID-1)
/*
* === Start XFS specific types and definitions ===
diff --git a/quotacheck.c b/quotacheck.c
index 0e7ba70..3377298 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.3 2001/04/05 08:26:56 jkar8572 Exp $"
+#ident "$Id: quotacheck.c,v 1.4 2001/04/11 10:12:36 jkar8572 Exp $"
#include <dirent.h>
#include <stdio.h>
@@ -814,7 +814,7 @@ static void check_all(void)
die(3, _("Too many mountpoints. Please report to: %s\n"), MY_EMAIL);
if (!(devlist[gotmnt] = (char *)get_device_name(mnt->mnt_fsname)))
continue;
- for (i = 0; i < gotmnt && strcmp(devlist[i], devlist[gotmnt]); i++);
+ for (i = 0; i < gotmnt && !devcmp(devlist[i], devlist[gotmnt]); i++);
/* We already have this mountpoint? */
if (i < gotmnt)
continue;
@@ -824,7 +824,7 @@ static void check_all(void)
else
mnt_fslabel = devlist[gotmnt - 1];
if ((flags & FL_ALL && (!(flags & FL_NOROOT) || strcmp(mnt->mnt_dir, "/"))) ||
- !strcmp(mntpoint, devlist[gotmnt - 1]) || !strcmp(mntpoint, mnt->mnt_dir)) {
+ devcmp(mntpoint, devlist[gotmnt - 1]) || dircmp(mntpoint, mnt->mnt_dir)) {
if (!strcmp(mnt->mnt_type, MNTTYPE_XFS)) {
debug(FL_DEBUG | FL_VERBOSE, _("Skipping %s [%s]\n"), mnt_fslabel,
mnt->mnt_dir);
diff --git a/quotaio.c b/quotaio.c
index f1b36c7..5d227af 100644
--- a/quotaio.c
+++ b/quotaio.c
@@ -65,6 +65,8 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt)
goto out_handle;
if (!(mnt_fsname = get_device_name(mnt->mnt_fsname)))
goto out_handle;
+ if (stat(mnt_fsname, &h->qh_stat) < 0)
+ memset(&h->qh_stat, 0, sizeof(struct stat));
h->qh_io_flags = 0;
h->qh_type = type;
sstrncpy(h->qh_quotadev, mnt_fsname, sizeof(h->qh_quotadev));
diff --git a/quotaio.h b/quotaio.h
index e9f88d5..edfbda3 100644
--- a/quotaio.h
+++ b/quotaio.h
@@ -9,6 +9,7 @@
#include <limits.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include "quota.h"
#include "mntopt.h"
@@ -81,6 +82,7 @@ struct quota_handle {
char qh_quotadev[PATH_MAX]; /* Device file is for */
int qh_type; /* Type of quotafile */
int qh_fmt; /* Quotafile format */
+ struct stat qh_stat; /* stat(2) for qh_quotadev */
struct quotafile_ops *qh_ops; /* Operations on quotafile */
struct util_dqinfo qh_info; /* Generic quotafile info */
};
diff --git a/quotaio_xfs.c b/quotaio_xfs.c
index 11a6320..653ce53 100644
--- a/quotaio_xfs.c
+++ b/quotaio_xfs.c
@@ -132,10 +132,8 @@ static struct dquot *xfs_read_dquot(struct quota_handle *h, qid_t id)
}
else {
xfs_kern2utildqblk(&dquot->dq_dqb, &xdqblk);
- return dquot;
}
- free(dquot);
- return NULL;
+ return dquot;
}
/*
@@ -242,11 +240,11 @@ static int xfs_report(struct quota_handle *h, int verbose)
#define XQM_ON(flag) ((info->qs_flags & (flag)) ? _("ON") : _("OFF"))
if (h->qh_type == USRQUOTA) {
- printf(_("Accounting: %s Enforcement: %s\n"),
+ printf(_("Accounting: %s; Enforcement: %s\n"),
XQM_ON(XFS_QUOTA_UDQ_ACCT), XQM_ON(XFS_QUOTA_UDQ_ENFD));
}
else { /* qh_type == USRQUOTA */
- printf(_("Accounting: %s Enforcement: %s\n"),
+ printf(_("Accounting: %s; Enforcement: %s\n"),
XQM_ON(XFS_QUOTA_GDQ_ACCT), XQM_ON(XFS_QUOTA_GDQ_ENFD));
}
#undef XQM_ON
@@ -258,13 +256,11 @@ static int xfs_report(struct quota_handle *h, int verbose)
#define XQM_ONDISK(flag) ((sbflags & (flag)) ? _("ON") : _("OFF"))
if ((sbflags = (info->qs_flags & 0xff00) >> 8) != 0) {
if (h->qh_type == USRQUOTA) {
- printf(_("Accounting [ondisk]: %s "
- "Enforcement [ondisk]: %s\n"),
+ printf(_("Accounting [ondisk]: %s; Enforcement [ondisk]: %s\n"),
XQM_ONDISK(XFS_QUOTA_UDQ_ACCT), XQM_ONDISK(XFS_QUOTA_UDQ_ENFD));
}
else { /* qh_type == USRQUOTA */
- printf(_("Accounting [ondisk]: %s "
- "Enforcement [ondisk]: %s\n"),
+ printf(_("Accounting [ondisk]: %s; Enforcement [ondisk]: %s\n"),
XQM_ONDISK(XFS_QUOTA_GDQ_ACCT), XQM_ONDISK(XFS_QUOTA_GDQ_ENFD));
}
#undef XQM_ONDISK
diff --git a/quotaon.c b/quotaon.c
index 6e8d17b..12cce13 100644
--- a/quotaon.c
+++ b/quotaon.c
@@ -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.1 2001/03/23 12:03:27 jkar8572 Exp $"
+#ident "$Id: quotaon.c,v 1.2 2001/04/11 10:12:36 jkar8572 Exp $"
/*
* Turn quota on/off for a filesystem.
@@ -62,12 +62,12 @@ static void usage(char *whoami)
/*
* Check to see if target appears in list of size cnt.
*/
-static int oneof(char *target, char *list[], int cnt)
+static int oneof(char *dir, char *dev, char *list[], int cnt)
{
int i;
for (i = 0; i < cnt; i++)
- if (strcmp(target, list[i]) == 0)
+ if (devcmp(dev, list[i]) || dircmp(dir, list[i]))
return (i);
return (-1);
}
@@ -169,8 +169,7 @@ int main(int argc, char **argv)
continue;
}
else {
- if ((argnum = oneof(mnt->mnt_dir, argv, argc)) >= 0 ||
- (argnum = oneof(mnt->mnt_fsname, argv, argc)) >= 0)
+ if ((argnum = oneof(mnt->mnt_dir, mnt->mnt_fsname, argv, argc)) >= 0)
done |= 1 << argnum;
else
continue;
diff --git a/quotaops.c b/quotaops.c
index 82bfb43..fed0168 100644
--- a/quotaops.c
+++ b/quotaops.c
@@ -34,7 +34,7 @@
#ident "$Copyright: (c) 1980, 1990 Regents of the University of California. $"
#ident "$Copyright: All rights reserved. $"
-#ident "$Id: quotaops.c,v 1.1 2001/03/23 12:03:27 jkar8572 Exp $"
+#ident "$Id: quotaops.c,v 1.2 2001/04/11 10:12:36 jkar8572 Exp $"
#include <rpc/rpc.h>
#include <sys/types.h>
@@ -208,7 +208,7 @@ static void merge_to_list(struct dquot *qlist, char *dev, u_int64_t blocks, u_in
struct dquot *q;
for (q = qlist; q; q = q->dq_next) {
- if (strcmp(dev, q->dq_h->qh_quotadev))
+ if (devcmp_handle(dev, q->dq_h))
continue;
/*
@@ -449,7 +449,7 @@ int readtimes(struct quota_handle **handles, int infd)
if (cvtatos(itime, iunits, &iseconds) < 0)
return -1;
for (i = 0; handles[i]; i++) {
- if (strcmp(fsp, handles[i]->qh_quotadev))
+ if (!devcmp_handle(fsp, handles[i]))
continue;
handles[i]->qh_info.dqi_bgrace = bseconds;
handles[i]->qh_info.dqi_igrace = iseconds;
diff --git a/quotasys.c b/quotasys.c
index ab05d50..b2dd507 100644
--- a/quotasys.c
+++ b/quotasys.c
@@ -351,13 +351,13 @@ struct quota_handle **create_handle_list(int count, char **mntpoints, int type,
while ((mnt = getmntent(mntf))) {
if (!(dev = get_device_name(mnt->mnt_fsname)))
continue;
- for (i = 0; i < gotmnt && strcmp(dev, hlist[i]->qh_quotadev); i++);
- /* We already have this device? (can happen when filesystem is mounted multiple times */
+ /* 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 what we want? */
- if (!strcmp(dev, mntpoints[i]) || !strcmp(mnt->mnt_dir, mntpoints[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) {
@@ -403,6 +403,34 @@ int dispose_handle_list(struct quota_handle **hlist)
}
/*
+ * Check whether given device name matches this quota handle
+ */
+int devcmp_handle(const char *dev, struct quota_handle *h)
+{
+ struct stat sbuf;
+
+ if (stat(dev, &sbuf) < 0)
+ return (strcmp(dev, h->qh_quotadev) == 0);
+ if (!S_ISBLK(sbuf.st_mode))
+ return (strcmp(dev, h->qh_quotadev) == 0);
+ if (sbuf.st_rdev != h->qh_stat.st_rdev)
+ return 0;
+ return 1;
+}
+
+/*
+ * Check whether two quota handles are for the same device
+ */
+int devcmp_handles(struct quota_handle *a, struct quota_handle *b)
+{
+ if (!S_ISBLK(a->qh_stat.st_mode) || !S_ISBLK(b->qh_stat.st_mode))
+ return (strcmp(a->qh_quotadev, b->qh_quotadev) == 0);
+ if (a->qh_stat.st_rdev != b->qh_stat.st_rdev)
+ return 0;
+ return 1;
+}
+
+/*
* Check kernel quota version
*/
diff --git a/quotasys.h b/quotasys.h
index f5db080..daeaeee 100644
--- a/quotasys.h
+++ b/quotasys.h
@@ -66,6 +66,12 @@ struct quota_handle **create_handle_list(int count, char **mntpoints, int type,
/* Dispose given list of handles */
int dispose_handle_list(struct quota_handle **hlist);
+/* Check whether given device name matches quota handle device */
+int devcmp_handle(const char *dev, struct quota_handle *h);
+
+/* Check whether two quota handles have same device */
+int devcmp_handles(struct quota_handle *a, struct quota_handle *b);
+
/* Warn about too new kernel */
void warn_new_kernel(int fmt);
diff --git a/repquota.c b/repquota.c
index 87cc6b7..4f78251 100644
--- a/repquota.c
+++ b/repquota.c
@@ -122,9 +122,9 @@ static void report_it(struct quota_handle *h, int type)
printf(_("*** Report for %s quotas on device %s\n"), type2name(type), h->qh_quotadev);
time2str(h->qh_info.dqi_bgrace, bgbuf, TF_ROUND);
time2str(h->qh_info.dqi_igrace, igbuf, TF_ROUND);
- printf("Block grace time: %s; Inode grace time: %s\n", bgbuf, igbuf);
- printf(" Block limits File limits\n");
- printf("User used soft hard grace used soft hard grace\n");
+ printf(_("Block grace time: %s; Inode grace time: %s\n"), bgbuf, igbuf);
+ printf(_(" Block limits File limits\n"));
+ printf(_("%-10s used soft hard grace used soft hard grace\n"), (type == USRQUOTA)?_("User"):_("Group"));
printf("----------------------------------------------------------------------\n");
if (h->qh_ops->scan_dquots(h, print) < 0)
diff --git a/setquota.8 b/setquota.8
index c4f9fcb..6f65dbd 100644
--- a/setquota.8
+++ b/setquota.8
@@ -4,23 +4,29 @@ setquota \- set disk quotas
.SH SYNOPSIS
.B /usr/sbin/setquota
[
-.B \-nr
+.B \-r
]
[
.B \-u
|
.B \-g
]
+[
+.B \-F
+.I quotaformat
+]
.I name
-.I filesystem
.I block-softlimit
.I block-hardlimit
.I inode-softlimit
.I inode-hardlimit
+.B \-a
+|
+.I filesystem
.LP
.B /usr/sbin/setquota
[
-.B \-nr
+.B \-r
]
[
.B \-u
@@ -28,9 +34,33 @@ setquota \- set disk quotas
.B \-g
]
[
-.B \-p protoname
+.B \-F
+.I quotaformat
+]
+[
+.B \-p
+.I protoname
]
.I name
+.B \-a
+|
+.I filesystem
+.LP
+.B /usr/sbin/setquota
+.B \-t
+[
+.B \-u
+|
+.B \-g
+]
+[
+.B \-F
+.I quotaformat
+]
+.I block-grace
+.I inode-grace
+.B \-a
+|
.I filesystem
.SH DESCRIPTION
.IX "setquota command" "" "\fLsetquota\fP \(em set disk quotas"
@@ -44,14 +74,13 @@ is a command line quota editor.
The filesystem, user/group name and new quotas for this
filesystem can be specified on the command line.
.TP
-.B -n
-Consider
-.I name
-to be a numeric ID (don't lookup user/group names).
-.TP
.B -r
Edit also remote quota use rpc.rquotad on remote server to set quota.
.TP
+.B -F \f2quotaformat\f1
+Perform setting for specified quota format. If this option isn't specified
+newest option found is used.
+.TP
.B -u
Set user quotas for named user. This is the default.
.TP
@@ -62,6 +91,18 @@ Set group quotas for named group.
Use quota settings of user or group
.I protoname
to set the quota for the named user or group.
+.TP
+.B -t
+Set grace times for users/groups. Times
+.B block-grace
+and
+.B inode-grace
+are specified in seconds.
+.TP
+.B -a
+Go through all filesystems with quota in
+.B /etc/mtab
+and perform setting.
.PP
To disable a quota, set the coresponding parameter to 0. To change quotas
for several filesystems, invoke once for each filesystem.