Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/bouyer-quota2]: src/usr.sbin/edquota Add -c option, which clears quota e...



details:   https://anonhg.NetBSD.org/src/rev/ee6ed446fa91
branches:  bouyer-quota2
changeset: 761114:ee6ed446fa91
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Mon Feb 07 20:31:20 2011 +0000

description:
Add -c option, which clears quota entries for the specified users/groups

diffstat:

 usr.sbin/edquota/edquota.8 |   22 ++++++++-
 usr.sbin/edquota/edquota.c |  118 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 135 insertions(+), 5 deletions(-)

diffs (238 lines):

diff -r 6e1f9af3d67b -r ee6ed446fa91 usr.sbin/edquota/edquota.8
--- a/usr.sbin/edquota/edquota.8        Mon Feb 07 20:30:39 2011 +0000
+++ b/usr.sbin/edquota/edquota.8        Mon Feb 07 20:31:20 2011 +0000
@@ -29,7 +29,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"    from: @(#)edquota.8     8.2 (Berkeley) 4/27/95
-.\"    $NetBSD: edquota.8,v 1.12.50.1 2011/02/06 22:18:38 bouyer Exp $
+.\"    $NetBSD: edquota.8,v 1.12.50.2 2011/02/07 20:31:20 bouyer Exp $
 .\"
 .Dd February 6, 2011
 .Dt EDQUOTA 8
@@ -74,6 +74,20 @@
 .Op Fl t Ar block grace time/inode grace time
 .Ar -d |
 .Ar groupname ...
+.Nm
+.Op Fl D
+.Op Fl H
+.Op Fl u
+.Fl c
+.Op Fl f Ar filesystem
+.Ar username ...
+.Nm
+.Op Fl D
+.Op Fl H
+.Fl g
+.Fl c
+.Op Fl f Ar filesystem
+.Ar groupname ...
 .Sh DESCRIPTION
 .Nm
 is a quota editor.
@@ -165,6 +179,12 @@
 per-user/group grace time. To edit the filesystem-wide grace time, use
 .Fl d .
 .Pp
+On quota2-enabled filesystems, the
+.Fl c
+flag cause edquota to clear quota entries for the specified users or groups.
+If disk or inode usages is not 0, limits are reverted to the default quota. 
+If disk and inode usages are 0, the existing quota entries are freed.
+.Pp
 The
 .Fl D
 flag cause edquota to print to the standard error property lists sent to
diff -r 6e1f9af3d67b -r ee6ed446fa91 usr.sbin/edquota/edquota.c
--- a/usr.sbin/edquota/edquota.c        Mon Feb 07 20:30:39 2011 +0000
+++ b/usr.sbin/edquota/edquota.c        Mon Feb 07 20:31:20 2011 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: edquota.c,v 1.29.16.9 2011/02/06 22:18:38 bouyer Exp $ */
+/*      $NetBSD: edquota.c,v 1.29.16.10 2011/02/07 20:31:20 bouyer Exp $ */
 /*
  * Copyright (c) 1980, 1990, 1993
  *     The Regents of the University of California.  All rights reserved.
@@ -41,7 +41,7 @@
 #if 0
 static char sccsid[] = "from: @(#)edquota.c    8.3 (Berkeley) 4/27/95";
 #else
-__RCSID("$NetBSD: edquota.c,v 1.29.16.9 2011/02/06 22:18:38 bouyer Exp $");
+__RCSID("$NetBSD: edquota.c,v 1.29.16.10 2011/02/07 20:31:20 bouyer Exp $");
 #endif
 #endif /* not lint */
 
@@ -113,6 +113,7 @@
 void   freeprivs(struct quotause *);
 int    alldigits(const char *);
 int    hasquota(struct fstab *, int, char **);
+static void clearpriv(int, char **, const char *, int);
 
 int Hflag = 0;
 int Dflag = 0;
@@ -131,6 +132,7 @@
        char *fs = NULL;
        int ch;
        int pflag = 0;
+       int cflag = 0;
 
        if (argc < 2)
                usage();
@@ -138,7 +140,7 @@
                errx(1, "permission denied");
        protoname = NULL;
        quotatype = USRQUOTA;
-       while ((ch = getopt(argc, argv, "DHdugp:s:h:t:f:")) != -1) {
+       while ((ch = getopt(argc, argv, "DHcdugp:s:h:t:f:")) != -1) {
                switch(ch) {
                case 'D':
                        Dflag++;
@@ -146,6 +148,9 @@
                case 'H':
                        Hflag++;
                        break;
+               case 'c':
+                       cflag++;
+                       break;
                case 'd':
                        dflag++;
                        break;
@@ -179,7 +184,7 @@
        argv += optind;
 
        if (pflag) {
-               if (soft || hard || grace || dflag)
+               if (soft || hard || grace || dflag || cflag)
                        usage();
                if ((protoid = getentry(protoname, quotatype)) == -1)
                        exit(1);
@@ -200,6 +205,9 @@
                u_int64_t softb, hardb, softi, hardi;
                time_t  graceb, gracei;
                char *str;
+
+               if (cflag)
+                       usage();
                if (soft) {
                        str = strsep(&soft, "/");
                        if (str[0] == '\0' || soft == NULL || soft[0] == '\0')
@@ -283,6 +291,12 @@
                }
                exit(0);
        }
+       if (cflag) {
+               if (dflag)
+                       usage();
+               clearpriv(argc, argv, fs, quotatype);
+               exit(0);
+       }
        tmpfd = mkstemp(tmpfil);
        fchown(tmpfd, getuid(), getgid());
        if (dflag) {
@@ -316,6 +330,8 @@
            "  edquota [-D] [-H] -g [-p groupname] [-f filesystem] -d | groupname ...\n"
            "  edquota [-D] [-u] [-f filesystem] [-s b#/i#] [-h b#/i#] [-t t#/t#] \\\n\t-d | username ...\n"
            "  edquota [-D] -g [-f filesystem] [-s b#/i#] [-h b#/i#] [-t t#/t#] \\\n\t-d | groupname ...\n"
+           "  edquota [-D] [-H] [-u] -c [-f filesystem] username ...\n"
+           "  edquota [-D] [-H] -g -c [-f filesystem] groupname ...\n"
            );
        exit(1);
 }
@@ -1060,3 +1076,97 @@
            qfextension[type]);
        return (1);
 }
+
+static void
+clearpriv(int argc, char **argv, const char *filesys, int quotatype)
+{
+       prop_array_t cmds, datas;
+       prop_dictionary_t protodict, dict, data, cmd;
+       struct plistref pref;
+       bool ret;
+       struct statvfs *fst;
+       int nfst, i, error;
+       int8_t error8;
+       int id;
+
+       /* build a generic command */
+       protodict = quota2_prop_create();
+       cmds = prop_array_create();
+       datas = prop_array_create();
+       if (protodict == NULL || cmds == NULL || datas == NULL) {
+               errx(1, "can't allocate proplist");
+       }
+
+       for ( ; argc > 0; argc--, argv++) {
+               if ((id = getentry(*argv, quotatype)) == -1)
+                       continue;
+               data = prop_dictionary_create();
+               if (data == NULL)
+                       errx(1, "can't allocate proplist");
+
+               ret = prop_dictionary_set_uint32(data, "id", id);
+               if (!ret)
+                       err(1, "prop_dictionary_set(id)");
+               if (!prop_array_add_and_rel(datas, data))
+                       err(1, "prop_array_add(data)");
+       }
+       if (!quota2_prop_add_command(cmds, "clear", qfextension[quotatype],
+           datas))
+               err(1, "prop_add_command");
+
+       if (!prop_dictionary_set(protodict, "commands", cmds))
+               err(1, "prop_dictionary_set(command)");
+
+       /* now loop over quota-enabled filesystems */
+       nfst = getmntinfo(&fst, MNT_WAIT);
+       if (nfst == 0)
+               errx(2, "no filesystems mounted!");
+
+       for (i = 0; i < nfst; i++) {
+               if (strcmp(fst[i].f_fstypename, "ffs") != 0 ||
+                   (fst[i].f_flag & ST_QUOTA) == 0)
+                       continue;
+               if (filesys && strcmp(fst[i].f_mntonname, filesys) != 0 &&
+                   strcmp(fst[i].f_mntfromname, filesys) != 0)
+                       continue;
+               if (Dflag) {
+                       fprintf(stderr, "message to kernel for %s:\n%s\n",
+                           fst[i].f_mntonname,
+                           prop_dictionary_externalize(protodict));
+               }
+
+               if (!prop_dictionary_send_syscall(protodict, &pref))
+                       err(1, "prop_dictionary_send_syscall");
+               if (quotactl(fst[i].f_mntonname, &pref) != 0)
+                       err(1, "quotactl");
+
+               if ((error = prop_dictionary_recv_syscall(&pref, &dict)) != 0) {
+                       errx(1, "prop_dictionary_recv_syscall: %s\n",
+                           strerror(error));
+               }
+
+               if (Dflag) {
+                       fprintf(stderr, "reply from kernel for %s:\n%s\n",
+                           fst[i].f_mntonname,
+                           prop_dictionary_externalize(dict));
+               }
+               if ((error = quota2_get_cmds(dict, &cmds)) != 0) {
+                       errx(1, "quota2_get_cmds: %s\n",
+                           strerror(error));
+               }
+               /* only one command, no need to iter */
+               cmd = prop_array_get(cmds, 0);
+               if (cmd == NULL)
+                       err(1, "prop_array_get(cmd)");
+
+               if (!prop_dictionary_get_int8(cmd, "return", &error8))
+                       err(1, "prop_get(return)");
+               if (error8) {
+                       fprintf(stderr, "clear %s quota entries on %s: %s\n",
+                           qfextension[quotatype], fst[i].f_mntonname,
+                           strerror(error8));
+               }
+               prop_object_release(dict);
+       }
+       prop_object_release(protodict);
+}



Home | Main Index | Thread Index | Old Index