summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjkar8572 <jkar8572>2001-05-02 09:32:22 +0000
committerjkar8572 <jkar8572>2001-05-02 09:32:22 +0000
commit84ec12aa207cb8d5323b63847bfd8115881f2886 (patch)
tree9533951fedda68167081028741a9ec3fd8ad547b
parent9c4a512419c660c0513db48e038169167e3e7d25 (diff)
downloadlinuxquota-84ec12aa207cb8d5323b63847bfd8115881f2886.tar.gz
Added mntopt.h to dependencies in Makefile.in.
Fixed MNTTYPE_REISER to proper string. sprintf->snprintf Merged Marco's patch with errstr(), configurable BSD behaviour Fixed bug in quota detection IO code now opens file only RO if possible. IO code now doesn't open file if not required. Fixed bug in quotaon. Updated all manpages.
-rw-r--r--Changelog20
-rw-r--r--Makefile.in6
-rw-r--r--bylabel.c6
-rw-r--r--common.c11
-rw-r--r--common.h6
-rwxr-xr-xconfigure111
-rw-r--r--configure.in7
-rw-r--r--convertquota.c43
-rw-r--r--edquota.836
-rw-r--r--edquota.c32
-rw-r--r--mntopt.h2
-rw-r--r--quot.83
-rw-r--r--quot.c14
-rw-r--r--quota.122
-rw-r--r--quota.c38
-rw-r--r--quotacheck.8193
-rw-r--r--quotacheck.c110
-rw-r--r--quotacheck_v1.c8
-rw-r--r--quotacheck_v2.c32
-rw-r--r--quotactl.280
-rw-r--r--quotaio.c44
-rw-r--r--quotaio.h4
-rw-r--r--quotaio_rpc.c7
-rw-r--r--quotaio_v1.c72
-rw-r--r--quotaio_v2.c31
-rw-r--r--quotaon.820
-rw-r--r--quotaon.c55
-rw-r--r--quotaon_xfs.c20
-rw-r--r--quotaops.c102
-rw-r--r--quotastats.c4
-rw-r--r--quotasys.c52
-rw-r--r--quotasys.h8
-rw-r--r--repquota.821
-rw-r--r--repquota.c28
-rw-r--r--rquota_server.c6
-rw-r--r--rquota_svc.c44
-rw-r--r--rquotad.88
-rw-r--r--set_limits_example.c14
-rw-r--r--setquota.818
-rw-r--r--setquota.c19
-rw-r--r--warnquota.c15
-rw-r--r--xqmstats.c6
42 files changed, 921 insertions, 457 deletions
diff --git a/Changelog b/Changelog
index 2f009ca..73a9492 100644
--- a/Changelog
+++ b/Changelog
@@ -39,6 +39,26 @@ Changes in quota-package from 2.00 to 3.01
* Fix up numerous compiler warnings and all the minor problems that revealed -
package now compiled with -Wall by default. (Jan Kara, Nathan Scott)
+* Rewrote the error output handler (now uses errstr function) which also
+ displays the correct programname of the program issueing the error.
+
+* Additional configure option BSD_BEHAVIOUR for more the old BSD behaviour
+ as wanted by some people.
+
+* EOF -> -1, sprintf -> snprintf fixes
+
+* Don't turn quotas on on NFS
+
+* Fixed quota format detection, related bugs in quotaon
+
+* IO code now allows readonly access, doesn't open quotafile when not needed
+
+* Fixed bug in old quotaformat initialization
+
+* quota(1) now exits with nonzero exitcode when over quota
+
+* Manpage cleanup
+
Changes in quota-package from 1.70 to 2.00
* Added patches from Steven Walker <smw8923@cmsu2.cmsu.edu> for supporting
diff --git a/Makefile.in b/Makefile.in
index cecd989..d06bfae 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -42,7 +42,7 @@ IOOBJS = quotaio.o quotaio_v1.o quotaio_v2.o quotaio_rpc.o quotaio_xfs.o
IOOBJS += $(RPCCLNTOBJS)
LIBOBJS = bylabel.o common.o quotasys.o pot.o $(IOOBJS)
LIBOBJS += @LIBMALLOC@
-INCLUDE = common.h quotasys.h bylabel.h
+INCLUDE = common.h quotasys.h bylabel.h mntopt.h
all: $(PROGS)
@@ -110,8 +110,8 @@ warnquota: $(INCLUDE) common.h warnquota.o $(LIBOBJS)
quotastats: quotastats.o pot.o
$(CC) $(LDFLAGS) -o $@ quotastats.o pot.o
-xqmstats: xqmstats.o pot.o
- $(CC) $(LDFLAGS) -o $@ xqmstats.o pot.o
+xqmstats: xqmstats.o common.o pot.o
+ $(CC) $(LDFLAGS) -o $@ xqmstats.o common.o pot.o
edquota: $(INCLUDE) quotaops.h quotaio.h edquota.o quotaops.o $(LIBOBJS)
$(CC) $(LDFLAGS) -o $@ edquota.o quotaops.o $(LIBOBJS)
diff --git a/bylabel.c b/bylabel.c
index 3ce77b2..d784931 100644
--- a/bylabel.c
+++ b/bylabel.c
@@ -167,7 +167,7 @@ static void uuidcache_init(void)
* (This is useful, if the cdrom on /dev/hdc must not
* be accessed.)
*/
- sprintf(device, "%s/%s", DEVLABELDIR, ptname);
+ snprintf(device, sizeof(device), "%s/%s", DEVLABELDIR, ptname);
if (!get_label_uuid(device, &label, uuid))
uuidcache_addentry(sstrdup(device), label, uuid);
}
@@ -231,7 +231,7 @@ static char *get_spec_by_uuid(const char *s)
return get_spec_by_x(UUID, uuid);
bad_uuid:
- fprintf(stderr, _("Found an invalid UUID: %s\n"), s);
+ errstr(_("Found an invalid UUID: %s\n"), s);
return NULL;
}
@@ -251,6 +251,6 @@ const char *get_device_name(const char *item)
else
rc = sstrdup(item);
if (!rc)
- fprintf(stderr, _("Error checking device name: %s\n"), item);
+ errstr(_("Error checking device name: %s\n"), item);
return rc;
}
diff --git a/common.c b/common.c
index 96f1747..91db878 100644
--- a/common.c
+++ b/common.c
@@ -20,12 +20,23 @@ void die(int ret, char *fmtstr, ...)
{
va_list args;
+ fprintf(stderr, "%s: ", progname);
va_start(args, fmtstr);
vfprintf(stderr, fmtstr, args);
va_end(args);
exit(ret);
}
+void errstr(char *fmtstr, ...)
+{
+ va_list args;
+
+ fprintf(stderr, "%s: ", progname);
+ va_start(args, fmtstr);
+ vfprintf(stderr, fmtstr, args);
+ va_end(args);
+}
+
void *smalloc(size_t size)
{
void *ret = malloc(size);
diff --git a/common.h b/common.h
index 3b779a5..175d038 100644
--- a/common.h
+++ b/common.h
@@ -9,9 +9,15 @@
#define MY_EMAIL "mvw@planets.elm.net, jack@suse.cz"
+/* Name of current program for error reporting */
+extern char *progname;
+
/* Finish programs being */
void die(int, char *, ...);
+/* Print an error */
+void errstr(char *, ...);
+
/* malloc() with error check */
void *smalloc(size_t);
diff --git a/configure b/configure
index 761f507..2d14aae 100755
--- a/configure
+++ b/configure
@@ -20,6 +20,8 @@ ac_help="$ac_help
ac_help="$ac_help
--enable-rpcsetquota=[yes/no] Use RPC for setting quotas [default=yes]."
ac_help="$ac_help
+ --enable-bsd_behaviour=[yes/no] Mimic BSD behaviour [default=yes]."
+ac_help="$ac_help
--enable-libefence=[yes/no] Use Electric Fence memory checks [default=no]."
# Initialize some variables set by options.
@@ -535,7 +537,7 @@ fi
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:539: checking for $ac_word" >&5
+echo "configure:541: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -565,7 +567,7 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:569: checking for $ac_word" >&5
+echo "configure:571: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -616,7 +618,7 @@ fi
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:620: checking for $ac_word" >&5
+echo "configure:622: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -648,7 +650,7 @@ fi
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:652: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:654: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -659,12 +661,12 @@ cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF
-#line 663 "configure"
+#line 665 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:670: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
@@ -690,12 +692,12 @@ if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:694: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:696: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:699: checking whether we are using GNU C" >&5
+echo "configure:701: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -704,7 +706,7 @@ else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:708: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:710: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@@ -723,7 +725,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:727: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:729: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -755,7 +757,7 @@ else
fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:759: checking how to run the C preprocessor" >&5
+echo "configure:761: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -770,13 +772,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 774 "configure"
+#line 776 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:780: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:782: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -787,13 +789,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 791 "configure"
+#line 793 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:797: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:799: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -804,13 +806,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 808 "configure"
+#line 810 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:814: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:816: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
@@ -835,12 +837,12 @@ fi
echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:839: checking for ANSI C header files" >&5
+echo "configure:841: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 844 "configure"
+#line 846 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -848,7 +850,7 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:852: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:854: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -865,7 +867,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 869 "configure"
+#line 871 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -883,7 +885,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 887 "configure"
+#line 889 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -904,7 +906,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 908 "configure"
+#line 910 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -915,7 +917,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-if { (eval echo configure:919: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:921: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
@@ -969,7 +971,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:973: checking for a BSD compatible install" >&5
+echo "configure:975: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1032,7 +1034,7 @@ fi
if test "x$with_ext2direct" != "xno"; then
echo $ac_n "checking for com_err in -lcom_err""... $ac_c" 1>&6
-echo "configure:1036: checking for com_err in -lcom_err" >&5
+echo "configure:1038: checking for com_err in -lcom_err" >&5
ac_lib_var=`echo com_err'_'com_err | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1040,7 +1042,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcom_err $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1044 "configure"
+#line 1046 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1051,7 +1053,7 @@ int main() {
com_err()
; return 0; }
EOF
-if { (eval echo configure:1055: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1057: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1079,7 +1081,7 @@ else
fi
echo $ac_n "checking for ext2fs_initialize in -lext2fs""... $ac_c" 1>&6
-echo "configure:1083: checking for ext2fs_initialize in -lext2fs" >&5
+echo "configure:1085: checking for ext2fs_initialize in -lext2fs" >&5
ac_lib_var=`echo ext2fs'_'ext2fs_initialize | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1087,7 +1089,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lext2fs $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1091 "configure"
+#line 1093 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1098,7 +1100,7 @@ int main() {
ext2fs_initialize()
; return 0; }
EOF
-if { (eval echo configure:1102: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1135,17 +1137,17 @@ fi
else
ac_safe=`echo "ext2fs/ext2fs.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for ext2fs/ext2fs.h""... $ac_c" 1>&6
-echo "configure:1139: checking for ext2fs/ext2fs.h" >&5
+echo "configure:1141: checking for ext2fs/ext2fs.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1144 "configure"
+#line 1146 "configure"
#include "confdefs.h"
#include <ext2fs/ext2fs.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1149: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1151: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1187,7 +1189,7 @@ EXT2LIBS=${LIBS}
LIBS=""
echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
-echo "configure:1191: checking for main in -lnsl" >&5
+echo "configure:1193: checking for main in -lnsl" >&5
ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1195,14 +1197,14 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1199 "configure"
+#line 1201 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:1206: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1208: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1230,7 +1232,7 @@ else
fi
echo $ac_n "checking for main in -lwrap""... $ac_c" 1>&6
-echo "configure:1234: checking for main in -lwrap" >&5
+echo "configure:1236: checking for main in -lwrap" >&5
ac_lib_var=`echo wrap'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1238,14 +1240,14 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lwrap $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1242 "configure"
+#line 1244 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:1249: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1251: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1276,17 +1278,17 @@ fi
if test ${ac_cv_lib_wrap_main} = yes; then
ac_safe=`echo "tcpd.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for tcpd.h""... $ac_c" 1>&6
-echo "configure:1280: checking for tcpd.h" >&5
+echo "configure:1282: checking for tcpd.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1285 "configure"
+#line 1287 "configure"
#include "confdefs.h"
#include <tcpd.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1290: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1292: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1316,12 +1318,12 @@ fi
fi
echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1320: checking for working const" >&5
+echo "configure:1322: checking for working const" >&5
if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1325 "configure"
+#line 1327 "configure"
#include "confdefs.h"
int main() {
@@ -1370,7 +1372,7 @@ ccp = (char const *const *) p;
; return 0; }
EOF
-if { (eval echo configure:1374: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1376: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
@@ -1391,21 +1393,21 @@ EOF
fi
echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:1395: checking for inline" >&5
+echo "configure:1397: checking for inline" >&5
if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
cat > conftest.$ac_ext <<EOF
-#line 1402 "configure"
+#line 1404 "configure"
#include "confdefs.h"
int main() {
} $ac_kw foo() {
; return 0; }
EOF
-if { (eval echo configure:1409: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1411: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_inline=$ac_kw; break
else
@@ -1455,6 +1457,14 @@ else
enable_rpcsetquota="yes"
fi
+# Check whether --enable-bsd_behaviour or --disable-bsd_behaviour was given.
+if test "${enable_bsd_behaviour+set}" = set; then
+ enableval="$enable_bsd_behaviour"
+ :
+else
+ enable_bsd_behaviour="yes"
+fi
+
# Check whether --enable-libefence or --disable-libefence was given.
if test "${enable_libefence+set}" = set; then
enableval="$enable_libefence"
@@ -1473,6 +1483,9 @@ fi
if test "$enable_rpcsetquota" = "yes" ; then
CFLAGS="-DRPC_SETQUOTA $CFLAGS"
fi
+if test "$enable_bsd_behaviour" = "yes" ; then
+ CFLAGS="-DBSD_BEHAVIOUR $CFLAGS"
+fi
if test "$enable_libefence" = "yes" ; then
LIBMALLOC="/usr/lib/libefence.a"
fi
diff --git a/configure.in b/configure.in
index 84606f3..4775238 100644
--- a/configure.in
+++ b/configure.in
@@ -71,6 +71,10 @@ AC_ARG_ENABLE(rpcsetquota,
[ --enable-rpcsetquota=[yes/no] Use RPC for setting quotas [default=yes].],
,
enable_rpcsetquota="yes")
+AC_ARG_ENABLE(bsd_behaviour,
+ [ --enable-bsd_behaviour=[yes/no] Mimic BSD behaviour [default=yes].],
+ ,
+ enable_bsd_behaviour="yes")
AC_ARG_ENABLE(libefence,
[ --enable-libefence=[yes/no] Use Electric Fence memory checks [default=no].],
,
@@ -85,6 +89,9 @@ fi
if test "$enable_rpcsetquota" = "yes" ; then
CFLAGS="-DRPC_SETQUOTA $CFLAGS"
fi
+if test "$enable_bsd_behaviour" = "yes" ; then
+ CFLAGS="-DBSD_BEHAVIOUR $CFLAGS"
+fi
if test "$enable_libefence" = "yes" ; then
LIBMALLOC="/usr/lib/libefence.a"
fi
diff --git a/convertquota.c b/convertquota.c
index c061459..6d3afbf 100644
--- a/convertquota.c
+++ b/convertquota.c
@@ -22,9 +22,17 @@
#include "bylabel.h"
char *mntpoint;
+char *progname;
int ucv, gcv;
struct quota_handle *qn; /* Handle of new file */
+static void usage(void)
+{
+ errstr(_("Utility for converting quota files.\nUsage:\n\t%s [-u] [-g] mountpoint\n"), progname);
+ errstr(_("Bugs to %s\n"), MY_EMAIL);
+ exit(1);
+}
+
void parse_options(int argcnt, char **argstr)
{
int ret;
@@ -34,15 +42,13 @@ void parse_options(int argcnt, char **argstr)
slash = argstr[0];
else
slash++;
+
sstrncpy(cmdname, slash, sizeof(cmdname));
while ((ret = getopt(argcnt, argstr, "Vugh:")) != -1) {
switch (ret) {
case '?':
case 'h':
-usage:
- printf(_("Utility for converting quota files.\nUsage:\n\t%s [-u] [-g] mountpoint\n"), cmdname);
- printf(_("Bugs to %s\n"), MY_EMAIL);
- exit(1);
+ usage();
case 'V':
version();
exit(0);
@@ -54,12 +60,15 @@ usage:
break;
}
}
+
if (optind + 1 != argcnt) {
puts(_("Bad number of arguments."));
- goto usage;
+ usage();
}
+
if (!(ucv | gcv))
ucv = 1;
+
mntpoint = argstr[optind];
}
@@ -79,7 +88,8 @@ int convert_dquot(struct dquot *dquot)
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));
+ errstr(_("Can't commit dquot for id %u: %s\n"),
+ (uint)dquot->dq_id, strerror(errno));
return -1;
}
return 0;
@@ -103,12 +113,14 @@ void convert_file(int type)
}
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);
+ if (!(qo = init_io(mnt, type, QF_VFSOLD, 1))) {
+ errstr(_("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));
+ errstr(_("Can't create file for %ss for new format on %s: %s\n"),
+ type2name(type), mntpoint, strerror(errno));
end_io(qo);
return;
}
@@ -117,7 +129,8 @@ void convert_file(int type)
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));
+ errstr(_("Can't rename new quotafile %s to name %s: %s\n"),
+ namebuf, qfname, strerror(errno));
free(qfname);
}
endmntent(mntf);
@@ -125,13 +138,19 @@ void convert_file(int type)
end_io(qn);
}
-int main(int argcnt, char **argstr)
+int main(int argc, char **argv)
{
- parse_options(argcnt, argstr);
+ gettexton();
+ progname = basename(argv[0]);
+
+ parse_options(argc, argv);
+
if (ucv)
convert_file(USRQUOTA);
+
if (ucv)
convert_file(GRPQUOTA);
+
return 0;
}
diff --git a/edquota.8 b/edquota.8
index 6b1085c..9dd1ba3 100644
--- a/edquota.8
+++ b/edquota.8
@@ -5,18 +5,23 @@ edquota \- edit user quotas
.B edquota
[
.B \-p
-.I proto-username
+.I protoname
] [
.B \-ug
+] [
+.B \-r
+] [
+.B \-F
+.I format-name
]
.IR username .\|.\|.
.LP
.B edquota
[
-.B \-r
-]
-[
.B \-ug
+] [
+.B \-F
+.I format-name
]
.B \-t
.SH DESCRIPTION
@@ -70,19 +75,30 @@ Edit the user quota. This is the default.
.B \-g
Edit the group quota.
.TP
-.B \-p
+.B \-p \f2protoname\f1
Duplicate the quotas of the prototypical user
specified for each user specified. This is the normal
mechanism used to initialize quotas for groups of users.
.TP
+.B \-F \f2format-name\f1
+Edit quota for specified format (ie. don't perform format autodetection).
+Possible format names are:
+.B vfsold
+(version 1 quota),
+.B vfsv0
+(version 2 quota),
+.B rpc
+(quota over NFS),
+.B xfs
+(quota on XFS filesystem)
+.TP
.B \-t
Edit the soft time limits for each filesystem.
-If the time limits are zero, the default time limits in
+In old quota format if the time limits are zero, the default time limits in
.B <linux/quota.h>
-are used.
-Time units of seconds, minutes, hours, days, weeks, and months
-are understood.
-Time limits are printed in the greatest possible time unit such that
+are used. In new quota format time limits must be specified (there is no default
+value set in kernel). Time units of seconds, minutes, hours, days, weeks, and months
+are understood. Time limits are printed in the greatest possible time unit such that
the value is greater than or equal to one.
.SH FILES
.PD 0
diff --git a/edquota.c b/edquota.c
index 52c92a1..84c9af7 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.3 2001/04/26 09:36:08 jkar8572 Exp $"
+#ident "$Id: edquota.c,v 1.4 2001/05/02 09:32:22 jkar8572 Exp $"
/*
* Disk quota editor.
@@ -58,22 +58,22 @@
#include "quotaio.h"
#include "common.h"
-static char tmpfil[] = _PATH_TMP "EdP.aXXXXXX";
+char *progname;
void usage(void)
{
#if defined(RPC_SETQUOTA)
- fprintf(stderr, "%s%s%s%s",
+ errstr("%s%s%s%s",
_("Usage:\tedquota [-r] [-u] [-F formatname] [-p username] username ...\n"),
- _("\tedquota [-r] -g [-p groupname] groupname ...\n"),
- _("\tedquota [-r] [-u] -t\n"), _("\tedquota [-r] -g -t\n"));
+ _("\tedquota [-r] -g [-F formatname] [-p groupname] groupname ...\n"),
+ _("\tedquota [-r] [-u] [-F formatname] -t\n"), _("\tedquota [-r] -g [-F formatname] -t\n"));
#else
- fprintf(stderr, "%s%s%s%s",
+ errstr("%s%s%s%s",
_("Usage:\tedquota [-u] [-F formatname] [-p username] username ...\n"),
- _("\tedquota -g [-p groupname] groupname ...\n"),
- _("\tedquota [-u] -t\n"), _("\tedquota -g -t\n"));
+ _("\tedquota -g [-F formatname] [-p groupname] groupname ...\n"),
+ _("\tedquota [-u] [-F formatname] -t\n"), _("\tedquota -g [-F formatname] -t\n"));
#endif
- fprintf(stderr, _("Bugs to: %s\n"), MY_EMAIL);
+ errstr(_("Bugs to: %s\n"), MY_EMAIL);
exit(1);
}
@@ -85,8 +85,10 @@ int main(int argc, char **argv)
char *protoname = NULL;
int tflag = 0, pflag = 0, rflag = 0, fmt = -1;
struct quota_handle **handles;
+ char *tmpfil, *tmpdir = NULL;
gettexton();
+ progname = basename(argv[0]);
if (argc < 2)
usage();
@@ -134,7 +136,7 @@ int main(int argc, char **argv)
if (tflag && argc != 0)
usage();
- handles = create_handle_list(0, NULL, quotatype, fmt, (rflag == 0));
+ handles = create_handle_list(0, NULL, quotatype, fmt, rflag ? 0 : IOI_LOCALONLY);
if (!handles[0]) {
dispose_handle_list(handles);
fputs(_("No filesystems with quota detected.\n"), stderr);
@@ -154,7 +156,7 @@ int main(int argc, char **argv)
for (pprivs = protoprivs, cprivs = curprivs; pprivs && cprivs;
pprivs = pprivs->dq_next, cprivs = cprivs->dq_next) {
if (!devcmp_handles(pprivs->dq_h, cprivs->dq_h))
- fprintf(stderr, _("fsname mismatch\n"));
+ errstr(_("fsname mismatch\n"));
else {
cprivs->dq_dqb.dqb_bsoftlimit =
pprivs->dq_dqb.dqb_bsoftlimit;
@@ -174,6 +176,13 @@ int main(int argc, char **argv)
}
umask(077);
+ if (getuid() == geteuid() && getgid() == getegid())
+ tmpdir = getenv("TMPDIR");
+ if (!tmpdir)
+ tmpdir = _PATH_TMP;
+ tmpfil = smalloc(strlen(tmpdir) + strlen("/EdP.aXXXXXX") + 1);
+ strcpy(tmpfil, tmpdir);
+ strcat(tmpfil, "/EdP.aXXXXXX");
tmpfd = mkstemp(tmpfil);
fchown(tmpfd, getuid(), getgid());
if (tflag) {
@@ -196,5 +205,6 @@ int main(int argc, char **argv)
close(tmpfd);
unlink(tmpfil);
+ free(tmpfil);
return 0;
}
diff --git a/mntopt.h b/mntopt.h
index c09b35f..b05f4e7 100644
--- a/mntopt.h
+++ b/mntopt.h
@@ -9,7 +9,7 @@
#define MNTTYPE_MINIX "minix" /* MINIX file system */
#define MNTTYPE_UFS "ufs" /* UNIX file system */
#define MNTTYPE_UDF "udf" /* OSTA UDF file system */
-#define MNTTYPE_REISER "reiser" /* Reiser file system */
+#define MNTTYPE_REISER "reiserfs" /* Reiser file system */
#define MNTTYPE_XFS "xfs" /* SGI XFS file system */
/* mount options */
diff --git a/quot.8 b/quot.8
index 5b96267..bab7418 100644
--- a/quot.8
+++ b/quot.8
@@ -9,7 +9,8 @@ quot \- summarize filesystem ownership
.IR quot
displays the number of kilobytes in the named
.I filesystem
-currently owned by each user or group.
+currently owned by each user or group. Note that this utility
+currently works only for XFS.
.SH OPTIONS
.TP
.B \-a
diff --git a/quot.c b/quot.c
index 940dbc5..d0c2f25 100644
--- a/quot.c
+++ b/quot.c
@@ -66,8 +66,8 @@ static int fflag;
static int gflag;
static int uflag;
static int vflag;
-static char *progname;
static time_t now;
+char *progname;
static void mounttable(char *);
static char *idname(__uint32_t, int);
@@ -76,7 +76,7 @@ static void creport(const char *, char *);
static void usage(void)
{
- fprintf(stderr, _("Usage: %s [-acfugvV] [filesystem...]\n"), progname);
+ errstr(_("Usage: %s [-acfugvV] [filesystem...]\n"));
exit(1);
}
@@ -135,7 +135,7 @@ static void mounttable(char *entry)
int doit;
if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
- fprintf(stderr, _("%s: no " MOUNTED " file\n"), progname);
+ errstr(_("no " MOUNTED " file\n"));
exit(1);
}
while ((mntp = getmntent(mtab)) != NULL) {
@@ -165,7 +165,7 @@ static void mounttable(char *entry)
}
}
if (entry != NULL)
- fprintf(stderr, _("%s: cannot locate block device for %s\n"), progname, entry);
+ errstr(_("cannot locate block device for %s\n"), entry);
endmntent(mtab);
}
@@ -361,7 +361,7 @@ static void checkXFS(const char *file, char *fsdir)
fsfd = open(fsdir, O_RDONLY);
if (fsfd < 0) {
- fprintf(stderr, _("%s: cannot open %s: %s\n"), progname, fsdir, strerror(errno));
+ errstr(_("cannot open %s: %s\n"), fsdir, strerror(errno));
exit(1);
}
sync();
@@ -381,8 +381,8 @@ static void checkXFS(const char *file, char *fsdir)
acctXFS(&buf[i]);
}
if (sts < 0) {
- fprintf(stderr, _("%s: XFS_IOC_FSBULKSTAT ioctl failed: %s\n"),
- progname, strerror(errno));
+ errstr(_("XFS_IOC_FSBULKSTAT ioctl failed: %s\n"),
+ strerror(errno));
exit(1);
}
free(buf);
diff --git a/quota.1 b/quota.1
index fec0b29..8cf75b8 100644
--- a/quota.1
+++ b/quota.1
@@ -3,19 +3,22 @@
quota \- display disk usage and limits
.SH SYNOPSIS
quota [
-.B -n
+.B -F
+.I format-name
] [
.B -guv | q
]
.br
quota [
-.B -n
+.B -F
+.I format-name
] [
.B -uv | q
] user
.br
quota [
-.B -n
+.B -F
+.I format-name
] [
.B -gv | q
] group
@@ -31,8 +34,17 @@ For filesystems that are NFS-mounted a call to the rpc.rquotad on
the server machine is performed to get the information.
.SH OPTIONS
.TP
-.B \-n
-Print info on numeric arguments e.g. uids and gids instead of users and groups
+.B \-F \f2format-name\f1
+Show quota for specified format (ie. don't perform format autodetection).
+Possible format names are:
+.B vfsold
+(version 1 quota),
+.B vfsv0
+(version 2 quota),
+.B rpc
+(quota over NFS),
+.B xfs
+(quota on XFS filesystem)
.TP
.B \-g
Print group quotas for the group
diff --git a/quota.c b/quota.c
index bea2865..f999cc6 100644
--- a/quota.c
+++ b/quota.c
@@ -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.4 2001/04/26 09:36:08 jkar8572 Exp $"
+#ident "$Id: quota.c,v 1.5 2001/05/02 09:32:22 jkar8572 Exp $"
/*
* Disk quota reporting program.
@@ -61,9 +61,10 @@
#include "common.h"
int qflag, vflag, fmt = -1;
+char *progname;
void usage(void);
-void showquotas(int type, qid_t id);
+int showquotas(int type, qid_t id);
void heading(int type, qid_t id, char *name, char *tag);
int main(int argc, char **argv)
@@ -73,6 +74,7 @@ int main(int argc, char **argv)
int i, ret, gflag = 0, uflag = 0;
gettexton();
+ progname = basename(argv[0]);
while ((ret = getopt(argc, argv, "guqvVF:")) != -1) {
switch (ret) {
@@ -122,38 +124,39 @@ int main(int argc, char **argv)
if (uflag && gflag)
usage();
+ ret = 0;
if (uflag)
for (; argc > 0; argc--, argv++)
- showquotas(USRQUOTA, user2uid(*argv));
+ ret |= showquotas(USRQUOTA, user2uid(*argv));
else if (gflag)
for (; argc > 0; argc--, argv++)
- showquotas(GRPQUOTA, group2gid(*argv));
- return 0;
+ ret |= showquotas(GRPQUOTA, group2gid(*argv));
+ return ret;
}
void usage(void)
{
- fprintf(stderr, "%s\n%s\n%s\n",
- _("Usage: quota [-guqvV] [-F quotaformat]"),
- _("\tquota [-qv] [-F quotaformat] -u username ..."),
- _("\tquota [-qv] [-F quotaformat] -g groupname ..."));
- fprintf(stderr, _("Bugs to: %s\n"), MY_EMAIL);
+ 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);
exit(1);
}
-void showquotas(int type, qid_t id)
+int showquotas(int type, qid_t id)
{
struct dquot *qlist, *q;
char *msgi, *msgb;
char timebuf[MAXTIMELEN];
char name[MAXNAMELEN];
struct quota_handle **handles;
- int lines = 0;
+ int lines = 0, over = 0;
time_t now;
time(&now);
id2name(id, type, name);
- handles = create_handle_list(0, NULL, type, fmt, 0);
+ handles = create_handle_list(0, NULL, type, fmt, IOI_READONLY);
qlist = getprivs(id, handles);
for (q = qlist; q; q = q->dq_next) {
if (!vflag && !q->dq_dqb.dqb_isoftlimit && !q->dq_dqb.dqb_ihardlimit
@@ -166,8 +169,10 @@ void showquotas(int type, qid_t id)
&& q->dq_dqb.dqb_curinodes >= q->dq_dqb.dqb_isoftlimit) {
if (q->dq_dqb.dqb_itime > now)
msgi = _("In file grace period on");
- else
+ else {
msgi = _("Over file quota on");
+ over = 1;
+ }
}
msgb = NULL;
if (q->dq_dqb.dqb_bhardlimit
@@ -177,8 +182,10 @@ void showquotas(int type, qid_t id)
&& toqb(q->dq_dqb.dqb_curspace) >= q->dq_dqb.dqb_bsoftlimit) {
if (q->dq_dqb.dqb_btime > now)
msgb = _("In block grace period on");
- else
+ else {
msgb = _("Over block quota on");
+ over = 1;
+ }
}
if (qflag) {
if ((msgi || msgb) && !lines++)
@@ -213,6 +220,7 @@ void showquotas(int type, qid_t id)
heading(type, id, name, _("none"));
freeprivs(qlist);
dispose_handle_list(handles);
+ return over;
}
void heading(int type, qid_t id, char *name, char *tag)
diff --git a/quotacheck.8 b/quotacheck.8
index 7270040..2a7489a 100644
--- a/quotacheck.8
+++ b/quotacheck.8
@@ -1,51 +1,90 @@
-.TH QUOTACHECK 8
+.TH quotacheck 8 "Mon Jul 17 2000"
.SH NAME
-quotacheck \- scan a filesystem for disk usages
+quotacheck \- scan a file system for disk usages, create, check and repair quota files
.SH SYNOPSIS
.B quotacheck
-[-g] [-u] [-v] -a
+[
+.B \-gucfinvdMmR
+] [
+.B \-F
+.I quota-format
+]
+.B \-a
+|
+.I filesystem
.br
-.B quotacheck
-[-g] [-u] [-v] filesys ...
.SH DESCRIPTION
-.I Quotacheck
-performs a filesystems scan for usage of files and directories, used
-by either user or group.
-XFS filesystems are ignored by
-.IR quotacheck ,
-since the XFS quota system is journaled and therefore inherently consistent.
-.PP
-The output is the quota file for the corresponding filesystem.
-By default the names for these files are:
+.B Quotacheck
+first checks old quota files for given filesystem and reads user / group limits
+from them (if it is creating new files -- see option
+.B -c
+-- this step is ommited, of course). Then performs a filesystem scan for usage
+of files and directories, used by either user or group. The output are new quota
+files for the corresponding filesystem. The names of these files are:
.br
\- A user scan:
-.I quota.user
+.B aquota.user
+or
+.B quota.user
+(depending on quota format)
.br
\- A group scan:
-.I quota.group
+.B aquota.group
+or
+.B quota.group
+.PP
+Old files are stored as
+.B aquota.user~
+/
+.B quota.user~
+and
+.B aquota.group~
+/
+.BR quota.group~ .
.PP
-The resulting file consists of a
-.I struct dqblk
-for each possible id up to the highest existing uid or gid and contains the
-values for the disk file and block usage and possibly excess time for these
-values. ( for definitions of
-.I struct dqblk
-see
-.I \<linux/quota.h\>
-)
+Old quota format (version 1) has no way of detecting quotafile corruption and so
+following text is meaningful only for version 2 quota format. When quota file is corrupted,
+.B quotacheck
+tries to save as many data as possible (which can sometimes result in bogus entries
+being created). Rescuing data might need user intervention. With no special options
+.B quotacheck
+will simply exit in that situation. When in interactive mode (option
+.BR -i )
+user is asked for an advice. Advices can be also provided from command line (see option
+.BR -n )
+which is handful when
+.B quotacheck
+is run automatically (ie. from script) and you can't
+afford
+.B quotacheck
+to fail.
.PP
-.I Quotacheck
-should be run each time the system boots and mounts non-valid filesystems.
+.B Quotacheck
+should be run each time the system boots and mounts non-valid file systems.
This is most likely to happen after a system crash.
.PP
-The speed of the scan decreases with the number of directories increasing.
-The time needed doubles when disk usage is doubled as well. A 100 MB partition
-used for 94% is scanned in 1 minute, the same partition used for 50% is
-done in 25 seconds.
+It is strongly recommended to run
+.B quotacheck
+with quotas turned off on concerned file system. Otherwise you can loose or damage some
+data in quota files. Also it is wise not to run
+.B quotacheck
+on live filesystem as directory scan might count bogus usage in that case. To prevent this
+.B quotacheck
+tries to remount filesystem read-only before starting the scan of filesystem and after
+the scan is done it remounts filesystem read-write. You can turn off this feature by
+option
+.BR \-m .
+You can also make
+.B quotacheck
+ignore that it didn't succeed when remounting filesystem read-only by option
+.BR \-M .
+.PP
+The speed of the scan decrease with the amount of directories increasing.
+The time needed doubles when disk usage is doubled as well.
.SH OPTIONS
.TP
.B \-v
-This way the program will give some useful information about what it is
+This way the program will give some usefull information about what it is
doing, plus some fancy stuff.
.TP
.B \-d
@@ -58,37 +97,93 @@ This flag tells the program to scan the disk and to count the files and
directories used by a certain uid. This is the default action.
.TP
.B \-g
-This flag forces the program to count the files and directories
+This flag forces the program to count the the files and directories
used by a certain gid.
.TP
+.B \-c
+Don't read old quota files. Just perform directory scan and dump usage.
+.TP
+.B \-f
+This flags forces checking of filesystem with quotas enabled. Note that doing
+this is not recomended as created quota files might be damaged or out of date.
+.TP
+.B \-M
+This flag forces checking of filesystem in read-write mode if remount fails. Do this only when
+you are sure no process will write to a filesystem while scanning.
+.TP
+.B \-m
+Don't try to remount filesystem read-only. See comment at option
+.BR \-M .
+.TP
+.B \-i
+Interactive mode. By default
+.B quotacheck
+exits when it finds some error. In interactive mode user is asked for an advice instead.
+See also option
+.BR \-n .
+.TP
+.B \-n
+Sometimes it may happen that more entries for the same id are found. Normally
+.B quotacheck
+exits or asks user. When this option is set first entry found is always used (this option
+works in interactive mode too).
+.TP
+.B \-F \f2format-name\f1
+Check quota quota for specified format (ie. don't perform format autodetection). This is
+recommended as detection might not work well on corrupted quotafiles.
+Possible format names are:
+.B vfsold
+(version 1 quota),
+.B vfsv0
+(version 2 quota),
+.B rpc
+(quota over NFS),
+.B xfs
+(quota on XFS filesystem)
+.TP
.B \-a
-Check all of the quotas for the filesystems mentioned in /etc/mtab. Both
-user and group quotas are checked as indicated by the /etc/mtab options.
+Check all filesystems in
+.B /etc/mtab
.TP
.B \-R
-When used in conjunction with \fP\-a\fR, all filesystems except the root
-filesystem are checked for quotas.
+When used together with
+.B \-a
+option, all filesystems except root filesystem are checked for quotas.
.SH NOTE
-.I Quotacheck
-should only be run as Super User. Non-privilidged users are presumably not allowed
+.B Quotacheck
+should only be run by super-user. Non-priviledged users are presumably not allowed
to read all the directories on the given filesystem.
.SH "SEE ALSO"
-quota(1), quotactl(2), fstab(5), quotaon(8), quotaoff(8), edquota(8),
-repquota(8), fsck(8)
+.BR quota (1),
+.BR quotactl (2),
+.BR fstab (5),
+.BR quotaon (8),
+.BR repquota (8),
+.BR convertquota (8),
+.BR setquota (8),
+.BR edquota (8),
+.BR fsck (8),
+.BR efsck (8),
+.BR e2fsck (8),
+.BR xfsck (8)
.SH FILES
.PD 0
-.TP 20
+.TP 15
.B aquota.user or aquota.group
-quota file at the filesystem root (version 2 quota, non-XFS filesystems)
-.TP 20
+located at filesystem root with user quotas (version 2 quota, non-XFS filesystems)
+.TP 15
.B quota.user or quota.group
-quota file at the filesystem root (version 1 quota, non-XFS filesystems)
+located at filesystem root with user quotas (version 1 quota, non-XFS filesystems)
.TP
.B /etc/mtab
-default filesystems
-.PD
-.SH "AUTHOR"
+names and locations of mounted filesystems
+.SH AUTHOR
+Jan Kara \<jack@suse.cz\>
+.br
+Based on old
+.B quotacheck
+by:
+.br
Edvard Tuinder \<ed@elm.net\>
.br
Marco van Wieringen \<mvw@planets.elm.net\>
-
diff --git a/quotacheck.c b/quotacheck.c
index f1f02a8..6c01ffd 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.7 2001/04/26 09:36:08 jkar8572 Exp $"
+#ident "$Id: quotacheck.c,v 1.8 2001/05/02 09:32:22 jkar8572 Exp $"
#include <dirent.h>
#include <stdio.h>
@@ -60,6 +60,7 @@ int files_done, dirs_done;
int flags, fmt = -1, cfmt; /* Options from command line; Quota format to use spec. by user; Actual format to check */
int uwant, gwant, ucheck, gcheck; /* Does user want to check user/group quota; Do we check user/group quota? */
char *mntpoint; /* Mountpoint to check */
+char *progname;
struct util_dqinfo old_info[MAXQUOTAS]; /* Loaded infos */
char extensions[MAXQUOTAS + 2][20] = INITQFNAMES; /* Extensions depending on quota type */
@@ -96,6 +97,8 @@ void debug(int df, char *fmtstr, ...)
if (!(flags & df))
return;
+
+ fprintf(stderr, "%s: ", progname);
va_start(args, fmtstr);
vfprintf(stderr, fmtstr, args);
va_end(args);
@@ -271,15 +274,16 @@ static inline void blit(void)
bitc %= BITS_SIZE;
}
+static void usage(void)
+{
+ printf(_("Utility for checking and repairing quota files.\n%s [-gucfinvdmMR] [-F <quota-format>] filesystem|-a\n"), progname);
+ printf(_("Bugs to %s\n"), MY_EMAIL);
+ exit(1);
+}
+
static void parse_options(int argcnt, char **argstr)
{
int ret;
- char *slash = strrchr(argstr[0], '/');
-
- if (slash)
- slash++;
- else
- slash = argstr[0];
while ((ret = getopt(argcnt, argstr, "VhcvugidnfF:mMRa")) != -1) {
switch (ret) {
@@ -328,17 +332,14 @@ static void parse_options(int argcnt, char **argstr)
exit(1);
break;
default:
- usage:
- printf(_("Utility for checking and repairing quota files.\n%s [-gucfinvdmMR] [-F <quota-format>] filesystem|-a\n"), slash);
- printf(_("Bugs to %s\n"), MY_EMAIL);
- exit(1);
+ usage();
}
}
if (!(uwant | gwant))
uwant = 1;
if (argcnt == optind && !(flags & FL_ALL)) {
fputs(_("Bad number of arguments.\n"), stderr);
- goto usage;
+ usage();
}
if (fmt == QF_XFS) {
fputs(_("XFS quota format needs no checking.\n"), stderr);
@@ -365,30 +366,27 @@ static int ext2_direct_scan(char *device)
ext2fs_inode_bitmap inode_dir_map;
if ((error = ext2fs_open(device, 0, 0, 0, unix_io_manager, &fs))) {
- fprintf(stderr, _("quotacheck: error (%d) while opening %s\n"), (int)error, device);
+ errstr(_("error (%d) while opening %s\n"), (int)error, device);
return -1;
}
if ((error = ext2fs_allocate_inode_bitmap(fs, "in-use inode map", &inode_used_map))) {
- fprintf(stderr, _("quotacheck: error (%d) while allocating inode file bitmap\n"),
- (int)error);
+ errstr(_("error (%d) while allocating inode file bitmap\n"), (int)error);
return -1;
}
if ((error = ext2fs_allocate_inode_bitmap(fs, "directory inode map", &inode_dir_map))) {
- fprintf(stderr,
- _("quotacheck: error (%d) while allocating inode directory bitmap\n"),
- (int)error);
+ errstr(_("errstr (%d) while allocating inode directory bitmap\n"), (int)error);
return -1;
}
if ((error = ext2fs_open_inode_scan(fs, inode_buffer_blocks, &scan))) {
- fprintf(stderr, _("quotacheck: error (%d) while opening inode scan\n"), (int)error);
+ errstr(_("error (%d) while opening inode scan\n"), (int)error);
return -1;
}
if ((error = ext2fs_get_next_inode(scan, &i_num, &inode))) {
- fprintf(stderr, _("quotacheck: error (%d) while starting inode scan\n"), (int)error);
+ errstr(_("error (%d) while starting inode scan\n"), (int)error);
return -1;
}
@@ -412,8 +410,7 @@ static int ext2_direct_scan(char *device)
}
if ((error = ext2fs_get_next_inode(scan, &i_num, &inode))) {
- fprintf(stderr, _("Something weird happened while scanning. Error %d\n"),
- (int)error);
+ errstr(_("Something weird happened while scanning. Error %d\n"), (int)error);
return -1;
}
}
@@ -447,9 +444,7 @@ static int scan_dir(char *pathname)
blit();
if ((lstat(de->d_name, &st)) == -1) {
- fprintf(stderr,
- _
- ("lstat Cannot stat `%s/%s': %s\nGuess you'd better run fsck first !\nexiting...\n"),
+ errstr(_("lstat Cannot stat `%s/%s': %s\nGuess you'd better run fsck first !\nexiting...\n"),
pathname, de->d_name, strerror(errno));
goto out;
}
@@ -556,25 +551,25 @@ static int process_file(char *mnt_fsname, struct mntent *mnt, int type)
}
}
else
- die(6,
- _
- ("Quota for %ss is enabled on mountpoint %s so quotacheck might damage the file.\n\
+ die(6, _("Quota for %ss is enabled on mountpoint %s so quotacheck might damage the file.\n\
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: %s\n"), strerror(errno));
+ die(4, _("Error while syncing quotas on %s: %s\n"), mnt_fsname, strerror(errno));
}
if (!(flags & FL_NEWFILE)) { /* Need to really buffer file? */
qfname = get_qf_name(mnt, type, cfmt);
if (!qfname) {
- fprintf(stderr, _("Cannot get quotafile name for %s\n"), mnt_fsname);
+ errstr(_("Cannot get quotafile name for %s\n"),
+ mnt_fsname);
return -1;
}
if ((fd = open(qfname, O_RDONLY)) < 0) {
- fprintf(stderr, _("Cannot open quotafile %s: %s\n"), qfname, strerror(errno));
+ errstr(_("Cannot open quotafile %s: %s\n"),
+ qfname, strerror(errno));
free(qfname);
return -1;
}
@@ -584,7 +579,8 @@ 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:
- fprintf(stderr, _("Too new quotafile format on %s\n"), mnt_fsname);
+ errstr(_("Too new quotafile format on %s\n"),
+ mnt_fsname);
ret = -1;
break;
case QF_VFSOLD:
@@ -606,6 +602,7 @@ static int rename_files(struct mntent *mnt, int type)
{
char *filename, newfilename[PATH_MAX];
struct stat st;
+ mode_t mode = S_IRUSR | S_IWUSR;
if (!(filename = get_qf_name(mnt, type, cfmt)))
die(2, _("Cannot get name of old quotafile on %s.\n"), mnt->mnt_dir);
@@ -615,11 +612,12 @@ static int rename_files(struct mntent *mnt, int type)
debug(FL_DEBUG | FL_VERBOSE, _("Old file not found.\n"));
goto rename_new;
}
- fprintf(stderr, _("Error while searching for old quota file %s: %s\n"), filename,
- strerror(errno));
+ errstr(_("Error while searching for old quota file %s: %s\n"),
+ filename, strerror(errno));
free(filename);
return -1;
}
+ mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
/* Backup old file */
strcpy(newfilename, filename);
/* Make backingup safe */
@@ -627,8 +625,8 @@ static int rename_files(struct mntent *mnt, int type)
if (newfilename[strlen(newfilename) - 1] != '~')
die(8, _("Name of quota file too long. Contact %s.\n"), MY_EMAIL);
if (rename(filename, newfilename) < 0) {
- fprintf(stderr, _("Cannot rename old quotafile %s to %s: %s\n"), filename,
- newfilename, strerror(errno));
+ errstr(_("Cannot rename old quotafile %s to %s: %s\n"),
+ filename, newfilename, strerror(errno));
free(filename);
return -1;
}
@@ -638,8 +636,13 @@ static int rename_files(struct mntent *mnt, int type)
strcpy(newfilename, filename);
sstrncat(newfilename, ".new", PATH_MAX);
if (rename(newfilename, filename) < 0) {
- fprintf(stderr, _("Cannot rename new quotafile %s to name %s: %s\n"), newfilename,
- filename, strerror(errno));
+ errstr(_("Cannot rename new quotafile %s to name %s: %s\n"),
+ newfilename, filename, strerror(errno));
+ free(filename);
+ return -1;
+ }
+ if (chmod(filename, mode) < 0) {
+ errstr(_("Cannot change permission of %s: %s\n"), filename, strerror(errno));
free(filename);
return -1;
}
@@ -660,7 +663,8 @@ static int dump_to_file(char *mnt_fsname, struct mntent *mnt, int type)
debug(FL_DEBUG | FL_VERBOSE, _("Dumping gathered data for %ss.\n"), type2name(type));
if (!(h = new_io(mnt, type, cfmt))) {
- fprintf(stderr, _("Cannot initialize IO on new quotafile: %s\n"), strerror(errno));
+ errstr(_("Cannot initialize IO on new quotafile: %s\n"),
+ strerror(errno));
return -1;
}
memcpy(&h->qh_info, old_info + type, sizeof(h->qh_info));
@@ -676,7 +680,8 @@ static int dump_to_file(char *mnt_fsname, struct mntent *mnt, int type)
h->qh_ops->commit_dquot(dquot);
}
if (end_io(h) < 0) {
- fprintf(stderr, _("Cannot finish IO on new quotafile: %s\n"), strerror(errno));
+ errstr(_("Cannot finish IO on new quotafile: %s\n"),
+ strerror(errno));
return -1;
}
if (rename_files(mnt, type) < 0)
@@ -687,9 +692,8 @@ static int dump_to_file(char *mnt_fsname, struct mntent *mnt, int type)
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))
- fprintf(stderr,
- _
- ("Cannot turn %s quotas on %s off and on: %s\nKernel won't know about changes quotacheck did.\n"),
+ 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));
free(filename);
}
@@ -741,9 +745,8 @@ mnt->mnt_dir);
}
}
else {
- fprintf(stderr,
- _
- ("Cannot remount filesystem mounted on %s read-only so counted values might not be right.\n\
+ errstr(
+ _("Cannot remount filesystem mounted on %s read-only so counted values might not be right.\n\
Please stop all programs writing to filesystem or use -m flag to force checking.\n"),
mnt->mnt_dir);
goto out;
@@ -790,12 +793,12 @@ static int detect_filename_format(struct mntent *mnt, int type)
struct stat statbuf;
char namebuf[PATH_MAX];
- sprintf(namebuf, "%s/%s.%s", mnt->mnt_dir, basenames[QF_VFSV0], extensions[type]);
+ snprintf(namebuf, PATH_MAX, "%s/%s.%s", mnt->mnt_dir, basenames[QF_VFSV0], extensions[type]);
if (!stat(namebuf, &statbuf))
return QF_VFSV0;
if (errno != ENOENT)
return -1;
- sprintf(namebuf, "%s/%s.%s", mnt->mnt_dir, basenames[QF_VFSOLD], extensions[type]);
+ snprintf(namebuf, PATH_MAX, "%s/%s.%s", mnt->mnt_dir, basenames[QF_VFSOLD], extensions[type]);
if (!stat(namebuf, &statbuf))
return QF_VFSOLD;
return -1;
@@ -845,7 +848,8 @@ static void check_all(void)
continue;
if (cfmt == -1) {
if ((cfmt = detect_filename_format(mnt, ucheck ? USRQUOTA : GRPQUOTA)) == -1) {
- fprintf(stderr, _("Cannot guess format from filename on %s. Please specify format on commandline.\n"), mnt_fslabel);
+ 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));
@@ -860,15 +864,17 @@ static void check_all(void)
free(devlist[i]);
}
-int main(int argcnt, char **argstr)
+int main(int argc, char **argv)
{
gettexton();
- parse_options(argcnt, argstr);
+ progname = basename(argv[0]);
+
+ parse_options(argc, argv);
warn_new_kernel(fmt);
check_all();
#ifdef DEBUG_MALLOC
- fprintf(stderr, _("Allocated %d bytes memory\nFree'd %d bytes\nLost %d bytes\n"),
+ errstr(_("Allocated %d bytes memory\nFree'd %d bytes\nLost %d bytes\n"),
malloc_mem, free_mem, malloc_mem - free_mem);
#endif
return 0;
diff --git a/quotacheck_v1.c b/quotacheck_v1.c
index db21c94..7fe8012 100644
--- a/quotacheck_v1.c
+++ b/quotacheck_v1.c
@@ -30,7 +30,8 @@ static void load_dquots(char *filename, int fd, int type)
die(1, _("Can't read entry for id %u from quotafile %s: %s\n"), (uint) id,
filename, strerror(errno));
if (err != sizeof(ddqblk)) {
- fprintf(stderr, _("Entry for id %u is truncated.\n"), (uint) id);
+ errstr(_("Entry for id %u is truncated.\n"),
+ (uint) id);
break;
}
dquot = add_dquot(id, type);
@@ -58,9 +59,8 @@ static int check_info(char *filename, int fd, int type)
die(1, _("Can't read first entry from quotafile %s: %s\n"), filename,
strerror(errno));
if (err != sizeof(ddqblk)) {
- fprintf(stderr,
- _
- ("WARNING: Quotafile %s was probably truncated. Can't save quota settings...\n"),
+ errstr(
+ _("WARNING - Quotafile %s was probably truncated. Can't save quota settings...\n"),
filename);
return -1;
}
diff --git a/quotacheck_v2.c b/quotacheck_v2.c
index 31a558f..da3ede3 100644
--- a/quotacheck_v2.c
+++ b/quotacheck_v2.c
@@ -53,11 +53,12 @@ static int check_info(char *filename, int fd, int type)
err = read(fd, &dinfo, sizeof(struct v2_disk_dqinfo));
if (err < 0) {
- fprintf(stderr, _("Can't read info from quota file %s: %s\n"), filename, strerror(errno));
+ errstr(_("Can't read info from quota file %s: %s\n"),
+ filename, strerror(errno));
return -1;
}
if (err != sizeof(struct v2_disk_dqinfo)) {
- fprintf(stderr, _("WARNING: Quota file %s was probably truncated. Can't save quota settings...\n"),
+ errstr(_("WARNING - Quota file %s was probably truncated. Can't save quota settings...\n"),
filename);
return -1;
}
@@ -69,7 +70,7 @@ static int check_info(char *filename, int fd, int type)
filesize = lseek(fd, 0, SEEK_END);
if (check_blkref(freeblk, blocks) < 0 || dflags & ~V2_DQF_MASK ||
check_blkref(freeent, blocks) < 0 || (filesize + V2_DQBLKSIZE - 1) >> V2_DQBLKSIZE_BITS != blocks) {
- fprintf(stderr, _("WARNING: Quota file info was corrupted.\n"));
+ errstr(_("WARNING - Quota file info was corrupted.\n"));
debug(FL_DEBUG, _("Size of file: %lu\nBlocks: %u Free block: %u Block with free entry: %u Flags: %x\n"),
(unsigned long)filesize, blocks, freeblk, freeent, dflags);
old_info[type].dqi_bgrace = MAX_DQ_TIME;
@@ -91,27 +92,27 @@ static int check_info(char *filename, int fd, int type)
return 0;
}
-/* Print error message */
+/* Print errstr message */
static void blk_corrupted(int *corrupted, uint * lblk, uint blk, char *fmtstr, ...)
{
va_list args;
if (!*corrupted) {
if (!(flags & (FL_VERBOSE | FL_DEBUG)))
- fprintf(stderr, _("Corrupted blocks: "));
+ errstr(_("Corrupted blocks: "));
}
if (flags & (FL_VERBOSE | FL_DEBUG)) {
va_start(args, fmtstr);
- fprintf(stderr, _("Block %u: "), blk);
+ errstr(_("Block %u: "), blk);
vfprintf(stderr, fmtstr, args);
fputc('\n', stderr);
va_end(args);
}
else if (*lblk != blk) {
if (!*corrupted)
- fprintf(stderr, "%u", blk);
+ errstr( "%u", blk);
else
- fprintf(stderr, ", %u", blk);
+ errstr( ", %u", blk);
}
*corrupted = 1;
*lblk = blk;
@@ -157,13 +158,13 @@ static int buffer_entry(dqbuf_t buf, uint blk, int *corrupted, uint * lblk, int
if (flags & FL_GUESSDQ) {
if (!(flags & (FL_DEBUG | FL_VERBOSE)))
fputc('\n', stderr);
- fprintf(stderr, _("Found more structures for ID %u. Using values: BHARD: %Ld BSOFT: %Ld IHARD: %Ld ISOFT: %Ld\n"),
+ errstr(_("Found more structures for ID %u. Using values: BHARD: %Ld BSOFT: %Ld IHARD: %Ld ISOFT: %Ld\n"),
(uint) id, (long long)fdq->dqb_bhardlimit, (long long)fdq->dqb_bsoftlimit,
(long long)fdq->dqb_ihardlimit, (long long)fdq->dqb_isoftlimit);
return 0;
}
else if (flags & FL_INTERACTIVE) {
- fprintf(stderr, _("\nFound more structures for ID %u. Values: BHARD: %Ld/%Ld BSOFT: %Ld/%Ld IHARD: %Ld/%Ld ISOFT: %Ld/%Ld\n"),
+ errstr(_("\nFound more structures for ID %u. Values: BHARD: %Ld/%Ld BSOFT: %Ld/%Ld IHARD: %Ld/%Ld ISOFT: %Ld/%Ld\n"),
(uint) id, (long long)fdq->dqb_bhardlimit, (long long)mdq.dqb_bhardlimit,
(long long)fdq->dqb_bsoftlimit, (long long)mdq.dqb_bsoftlimit,
(long long)fdq->dqb_ihardlimit, (long long)mdq.dqb_ihardlimit,
@@ -178,7 +179,7 @@ static int buffer_entry(dqbuf_t buf, uint blk, int *corrupted, uint * lblk, int
}
}
else {
- fprintf(stderr, _("ID %u has more structures. User intervention needed (use -i for interactive mode or -n for automatic answer).\n"),
+ errstr(_("ID %u has more structures. User intervention needed (use -i for interactive mode or -n for automatic answer).\n"),
(uint) id);
return -1;
}
@@ -296,12 +297,13 @@ static int check_header(char *filename, int fd, int type)
if (err < 0)
die(1, _("Can't read header from quotafile %s: %s\n"), filename, strerror(errno));
if (err != sizeof(head)) {
- fprintf(stderr, _("WARNING: Quotafile %s was probably truncated. Can't save quota settings...\n"),
+ errstr(_("WARNING - Quotafile %s was probably truncated. Can't save quota settings...\n"),
filename);
return -1;
}
if (__le32_to_cpu(head.dqh_magic) != magics[type] || __le32_to_cpu(head.dqh_version) > known_versions[type])
- fprintf(stderr, _("WARNING: Quota file %s has corrupted headers\n"), filename);
+ errstr(_("WARNING - Quota file %s has corrupted headers\n"),
+ filename);
debug(FL_DEBUG, _("Headers checked.\n"));
return 0;
}
@@ -328,7 +330,7 @@ int v2_buffer_file(char *filename, int fd, int type)
if (check_tree_ref(0, V2_DQTREEOFF, blocks, 1, &corrupted, &lastblk) >= 0)
ret = check_tree_blk(fd, V2_DQTREEOFF, 0, type, blocks, &corrupted, &lastblk);
else
- fprintf(stderr, _("Can't gather quota data. Tree root node corrupted.\n"));
+ errstr(_("Can't gather quota data. Tree root node corrupted.\n"));
#ifdef DEBUG_MALLOC
free_mem += (blocks + 7) >> 3;
#endif
@@ -336,7 +338,7 @@ int v2_buffer_file(char *filename, int fd, int type)
if (corrupted) {
if (!(flags & (FL_VERBOSE | FL_DEBUG)))
fputc('\n', stderr);
- fprintf(stderr, _("WARNING: Some data might be changed due to corruption.\n"));
+ errstr(_("WARNING - Some data might be changed due to corruption.\n"));
}
else
debug(FL_DEBUG | FL_VERBOSE, _("Not found any corrupted blocks. Congratulations.\n"));
diff --git a/quotactl.2 b/quotactl.2
index 006c86e..e3fb145 100644
--- a/quotactl.2
+++ b/quotactl.2
@@ -6,7 +6,7 @@ quotactl \- manipulate disk quotas
.B #include <linux/quota.h>
.B #include <linux/xqm.h>
.LP
-.B int quotactl(int cmd, char \(**special, int uid, caddr_t addr)
+.B long quotactl(int cmd, char \(**special, qid_t id, caddr_t addr)
.fi
.SH DESCRIPTION
.LP
@@ -48,7 +48,7 @@ program. This call is restricted to the super-user.
Turn off quotas for a filesystem.
.I addr
and
-.I uid
+.I id
are ignored.
This call is restricted to the super-user.
.TP
@@ -57,7 +57,7 @@ Get disk quota limits and current usage for user or group
.IR id .
.I addr
is a pointer to a
-.B dqblk
+.B mem_dqblk
structure (defined in
.BR <linux/quota.h> ).
Only the super-user may get the quotas of a user other than himself.
@@ -67,7 +67,7 @@ Set disk quota limits and current usage for user or group
.IR id .
.I addr
is a pointer to a
-.B dqblk
+.B mem_dqblk
structure (defined in
.BR <linux/quota.h> ).
This call is restricted to the super-user.
@@ -77,7 +77,17 @@ Set disk quota limits for user or group
.IR id .
.I addr
is a pointer to a
-.B dqblk
+.B mem_dqblk
+structure (defined in
+.BR <linux/quota.h> ).
+This call is restricted to the super-user.
+.TP
+.SB Q_SETUSE
+Set current usage for user or group
+.IR id .
+.I addr
+is a pointer to a
+.B mem_dqblk
structure (defined in
.BR <linux/quota.h> ).
This call is restricted to the super-user.
@@ -89,9 +99,63 @@ If
is null then all filesystems with active quotas are sync'ed.
.I addr
and
-.I uid
+.I id
+are ignored.
+.TP
+.SB Q_GETSTATS
+Get statistics and other generic information about quota subsystem.
+.I addr
+should be a pointer to
+.B dqstats
+structure (defined in
+.BR <linux/quota.h> )
+in which data should be stored.
+.I special
+and
+.I id
are ignored.
.PP
+New quota format also allows following additional calls:
+.TP 15
+.SB Q_GETINFO
+Get information (like grace times) about quotafile.
+.I addr
+should be a pointer to
+.B mem_dqinfo
+structure (defined in
+.IR <linux/quota.h> ).
+.I id
+is ignored.
+.TP
+.SB Q_SETINFO
+Set information about quotafile.
+.I addr should be a pointer to
+.B mem_dqinfo
+structure (defined in
+.IR <linux/quota.h> ).
+.I id
+is ignored. This operation is restricted to super-user.
+.TP
+.SB Q_SETGRACE
+Set grace times in information about quotafile.
+.I addr should be a pointer to
+.B mem_dqinfo
+structure (defined in
+.IR <linux/quota.h> ).
+.I id
+is ignored. This operation is restricted to super-user.
+.TP
+.SB Q_SETFLAGS
+Set flags in information about quotafile. These flags are defined in
+.IR <linux/quota.h> .
+Note that there are currently no defined flags.
+.I addr should be a pointer to
+.B mem_dqinfo
+structure (defined in
+.IR <linux/quota.h> ).
+.I id
+is ignored. This operation is restricted to super-user.
+.TP
For XFS filesystems making use of the XFS Quota Manager (XQM), the
above commands are bypassed and the following commands are used:
.TP 15
@@ -115,7 +179,7 @@ This call is restricted to the superuser.
.TP
.SB Q_XGETQUOTA
Get disk quota limits and current usage for user
-.IR uid .
+.IR id .
.I addr
is a pointer to a
.B fs_disk_quota
@@ -125,7 +189,7 @@ Only the superuser may get the quotas of a user other than himself.
.TP
.SB Q_XSETQLIM
Set disk quota limits for user
-.IR uid .
+.IR id .
.I addr
is a pointer to a
.B fs_disk_quota
diff --git a/quotaio.c b/quotaio.c
index 5d227af..d54f731 100644
--- a/quotaio.c
+++ b/quotaio.c
@@ -54,7 +54,7 @@ int detect_qf_format(int fd, int type)
/*
* Detect quota format and initialize quota IO
*/
-struct quota_handle *init_io(struct mntent *mnt, int type, int fmt)
+struct quota_handle *init_io(struct mntent *mnt, int type, int fmt, int flags)
{
char *qfname = NULL;
int fd = -1, kernfmt;
@@ -68,12 +68,14 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt)
if (stat(mnt_fsname, &h->qh_stat) < 0)
memset(&h->qh_stat, 0, sizeof(struct stat));
h->qh_io_flags = 0;
+ if (flags & IOI_READONLY)
+ h->qh_io_flags |= IOFL_RO;
h->qh_type = type;
sstrncpy(h->qh_quotadev, mnt_fsname, sizeof(h->qh_quotadev));
free((char *)mnt_fsname);
if (!strcmp(mnt->mnt_type, MNTTYPE_NFS)) { /* NFS filesystem? */
if (fmt != -1 && fmt != QF_RPC) { /* User wanted some other format? */
- fprintf(stderr, _("Only RPC quota format is allowed on NFS filesystem.\n"));
+ errstr(_("Only RPC quota format is allowed on NFS filesystem.\n"));
goto out_handle;
}
#ifdef RPC
@@ -82,14 +84,14 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt)
h->qh_ops = &quotafile_ops_rpc;
return h;
#else
- fprintf(stderr, _("RPC quota format not compiled.\n"));
+ errstr(_("RPC quota format not compiled.\n"));
goto out_handle;
#endif
}
if (!strcmp(mnt->mnt_type, MNTTYPE_XFS)) { /* XFS filesystem? */
if (fmt != -1 && fmt != QF_XFS) { /* User wanted some other format? */
- fprintf(stderr, _("Only XFS quota format is allowed on XFS filesystem.\n"));
+ errstr(_("Only XFS quota format is allowed on XFS filesystem.\n"));
goto out_handle;
}
h->qh_fd = -1;
@@ -107,14 +109,14 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt)
fmt = kernfmt; /* Default is kernel used format */
}
if (!(qfname = get_qf_name(mnt, type, fmt))) {
- fprintf(stderr, _("Can't get quotafile name.\n"));
+ errstr(_("Can't get quotafile name.\n"));
goto out_handle;
}
- if (qfname[0]) { /* Has format any quotafile to open? */
+ if (qfname[0] && (!QIO_ENABLED(h) || flags & IOI_OPENFILE)) { /* Need to open file? */
/* We still need to open file for operations like 'repquota' */
- if ((fd = open(qfname, O_RDWR)) < 0) {
- fprintf(stderr, _("Can't open quotafile %s: %s\n"), qfname,
- strerror(errno));
+ if ((fd = open(qfname, QIO_RO(h) ? O_RDONLY : O_RDWR)) < 0) {
+ errstr(_("Can't open quotafile %s: %s\n"),
+ qfname, strerror(errno));
goto out_handle;
}
flock(fd, LOCK_EX);
@@ -124,11 +126,12 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt)
/* Check file format */
h->qh_fmt = detect_qf_format(fd, type);
if (h->qh_fmt == -2) {
- fprintf(stderr, _("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) {
- fprintf(stderr, _("Quotafile format detected differs from the specified one (or the one kernel uses on the file).\n"));
+ errstr(_("Quotafile format detected differs from the specified one (or the one kernel uses on the file).\n"));
goto out_handle;
}
}
@@ -143,8 +146,10 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt)
h->qh_ops = &quotafile_ops_2;
memset(&h->qh_info, 0, sizeof(h->qh_info));
- if (h->qh_ops->init_io && h->qh_ops->init_io(h) < 0)
+ if (h->qh_ops->init_io && h->qh_ops->init_io(h) < 0) {
+ errstr(_("Can't initialize quota on %s: %s\n"), h->qh_quotadev, strerror(errno));
goto out_lock;
+ }
return h;
out_lock:
if (fd != -1)
@@ -170,7 +175,7 @@ struct quota_handle *new_io(struct mntent *mnt, int type, int fmt)
if (fmt == -1)
fmt = QF_VFSV0; /* Use the newest format */
else if (fmt == QF_RPC || fmt == QF_XFS) {
- fprintf(stderr, _("Creation of %s quota format is not supported.\n"),
+ errstr(_("Creation of %s quota format is not supported.\n"),
fmt == QF_RPC ? "RPC" : "XFS");
return NULL;
}
@@ -180,7 +185,8 @@ struct quota_handle *new_io(struct mntent *mnt, int type, int fmt)
sstrncat(namebuf, ".new", PATH_MAX);
free(qfname);
if ((fd = open(namebuf, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0) {
- fprintf(stderr, _("Can't create new quotafile %s: %s\n"), namebuf, strerror(errno));
+ errstr(_("Can't create new quotafile %s: %s\n"),
+ namebuf, strerror(errno));
return NULL;
}
if (!(mnt_fsname = get_device_name(mnt->mnt_fsname)))
@@ -215,15 +221,13 @@ struct quota_handle *new_io(struct mntent *mnt, int type, int fmt)
*/
int end_io(struct quota_handle *h)
{
- int ret;
-
if (h->qh_io_flags & IOFL_INFODIRTY) {
- if (h->qh_ops->write_info && (ret = h->qh_ops->write_info(h)) >= 0)
- return ret;
+ if (h->qh_ops->write_info && h->qh_ops->write_info(h) < 0)
+ return -1;
h->qh_io_flags &= ~IOFL_INFODIRTY;
}
- if (h->qh_ops->end_io && (ret = h->qh_ops->end_io(h)) >= 0)
- return ret;
+ if (h->qh_ops->end_io && h->qh_ops->end_io(h) < 0)
+ return -1;
flock(h->qh_fd, LOCK_UN);
close(h->qh_fd);
free(h);
diff --git a/quotaio.h b/quotaio.h
index edfbda3..acd86c1 100644
--- a/quotaio.h
+++ b/quotaio.h
@@ -62,6 +62,7 @@
#define IOFL_QUOTAON 0x01 /* Is quota enabled in kernel? */
#define IOFL_INFODIRTY 0x02 /* Did info change? */
+#define IOFL_RO 0x04 /* Just RO access? */
struct quotafile_ops;
@@ -131,12 +132,13 @@ static inline void mark_quotafile_info_dirty(struct quota_handle *h)
}
#define QIO_ENABLED(h) ((h)->qh_io_flags & IOFL_QUOTAON)
+#define QIO_RO(h) ((h)->qh_io_flags & IOFL_RO)
/* Detect format of given quotafile */
int detect_qf_format(int fd, int type);
/* Check quota format used on specified medium and initialize it */
-struct quota_handle *init_io(struct mntent *mnt, int type, int fmt);
+struct quota_handle *init_io(struct mntent *mnt, int type, int fmt, int flags);
/* Create new quotafile of specified format on given filesystem */
struct quota_handle *new_io(struct mntent *mnt, int type, int fmt);
diff --git a/quotaio_rpc.c b/quotaio_rpc.c
index cbdfe8b..3482de8 100644
--- a/quotaio_rpc.c
+++ b/quotaio_rpc.c
@@ -6,9 +6,11 @@
#include <errno.h>
#include <sys/types.h>
+#include "common.h"
#include "quotaio.h"
#include "dqblk_rpc.h"
#include "rquota_client.h"
+#include "pot.h"
static struct dquot *rpc_read_dquot(struct quota_handle *h, qid_t id);
static int rpc_commit_dquot(struct dquot *dquot);
@@ -47,6 +49,11 @@ static struct dquot *rpc_read_dquot(struct quota_handle *h, qid_t id)
static int rpc_commit_dquot(struct dquot *dquot)
{
#ifdef RPC
+ if (QIO_RO(dquot->dq_h)) {
+ errstr(_("Trying to write quota to readonly quotafile on %s\n"), dquot->dq_h->qh_quotadev);
+ errno = EPERM;
+ return -1;
+ }
rpc_rquota_set(QCMD(Q_RPC_SETQUOTA, dquot->dq_h->qh_type), dquot);
return 0;
#else
diff --git a/quotaio_v1.c b/quotaio_v1.c
index 31b47e9..405479e 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.3 2001/04/04 17:47:50 jkar8572 Exp $"
+#ident "$Id: quotaio_v1.c,v 1.4 2001/05/02 09:32:22 jkar8572 Exp $"
#include <unistd.h>
#include <errno.h>
@@ -127,10 +127,17 @@ static int v1_init_io(struct quota_handle *h)
if (QIO_ENABLED(h)) {
struct v1_kern_dqblk kdqblk;
- if (quotactl(QCMD(Q_V1_GETQUOTA, h->qh_type), h->qh_quotadev, 0, (void *)&kdqblk) <
- 0) return -1;
- h->qh_info.dqi_bgrace = kdqblk.dqb_btime;
- h->qh_info.dqi_igrace = kdqblk.dqb_itime;
+ if (quotactl(QCMD(Q_V1_GETQUOTA, h->qh_type), h->qh_quotadev, 0, (void *)&kdqblk) < 0) {
+ if (errno == EPERM) { /* We have no permission to get this information? */
+ h->qh_info.dqi_bgrace = h->qh_info.dqi_igrace = 0; /* It hopefully won't be needed */
+ }
+ else
+ return -1;
+ }
+ else {
+ h->qh_info.dqi_bgrace = kdqblk.dqb_btime;
+ h->qh_info.dqi_igrace = kdqblk.dqb_itime;
+ }
}
else {
struct v1_disk_dqblk ddqblk;
@@ -168,15 +175,20 @@ static int v1_new_io(struct quota_handle *h)
*/
static int v1_write_info(struct quota_handle *h)
{
+ if (QIO_RO(h)) {
+ errstr(_("Trying to write info to readonly quotafile on %s.\n"), h->qh_quotadev);
+ errno = EPERM;
+ return -1;
+ }
if (QIO_ENABLED(h)) {
struct v1_kern_dqblk kdqblk;
- if (quotactl(QCMD(Q_V1_GETQUOTA, h->qh_type), h->qh_quotadev, 0, (void *)&kdqblk) <
- 0) return -1;
+ if (quotactl(QCMD(Q_V1_GETQUOTA, h->qh_type), h->qh_quotadev, 0, (void *)&kdqblk) < 0)
+ return -1;
kdqblk.dqb_btime = h->qh_info.dqi_bgrace;
kdqblk.dqb_itime = h->qh_info.dqi_igrace;
- if (quotactl(QCMD(Q_V1_SETQUOTA, h->qh_type), h->qh_quotadev, 0, (void *)&kdqblk) <
- 0) return -1;
+ if (quotactl(QCMD(Q_V1_SETQUOTA, h->qh_type), h->qh_quotadev, 0, (void *)&kdqblk) < 0)
+ return -1;
}
else {
struct v1_disk_dqblk ddqblk;
@@ -195,7 +207,7 @@ static int v1_write_info(struct quota_handle *h)
/*
* Read a dqblk struct from the quotafile.
- * User can use 'errno' to detect error.
+ * User can use 'errno' to detect errstr.
*/
static struct dquot *v1_read_dquot(struct quota_handle *h, qid_t id)
{
@@ -217,21 +229,19 @@ static struct dquot *v1_read_dquot(struct quota_handle *h, qid_t id)
else {
lseek(h->qh_fd, (long)V1_DQOFF(id), SEEK_SET);
switch (read(h->qh_fd, &ddqblk, sizeof(ddqblk))) {
- case 0: /* EOF */
- /*
- * Convert implicit 0 quota (EOF) into an
- * explicit one (zero'ed dqblk)
- */
- memset(&dquot->dq_dqb, 0, sizeof(struct util_dqblk));
-
- break;
- case sizeof(struct v1_disk_dqblk): /* OK */
- v1_disk2memdqblk(&dquot->dq_dqb, &ddqblk);
-
- break;
- default: /* ERROR */
- free(dquot);
- return NULL;
+ case 0: /* EOF */
+ /*
+ * Convert implicit 0 quota (EOF) into an
+ * explicit one (zero'ed dqblk)
+ */
+ memset(&dquot->dq_dqb, 0, sizeof(struct util_dqblk));
+ break;
+ case sizeof(struct v1_disk_dqblk): /* OK */
+ v1_disk2memdqblk(&dquot->dq_dqb, &ddqblk);
+ break;
+ default: /* ERROR */
+ free(dquot);
+ return NULL;
}
}
return dquot;
@@ -239,19 +249,23 @@ static struct dquot *v1_read_dquot(struct quota_handle *h, qid_t id)
/*
* Write a dqblk struct to the quotafile.
- * User can process use 'errno' to detect error
+ * User can process use 'errno' to detect errstr
*/
static int v1_commit_dquot(struct dquot *dquot)
{
struct v1_disk_dqblk ddqblk;
struct quota_handle *h = dquot->dq_h;
+ if (QIO_RO(h)) {
+ errstr(_("Trying to write quota to readonly quotafile on %s\n"), h->qh_quotadev);
+ errno = EPERM;
+ return -1;
+ }
if (QIO_ENABLED(h)) { /* Kernel uses same file? */
struct v1_kern_dqblk kdqblk;
v1_util2kerndqblk(&kdqblk, &dquot->dq_dqb);
- if (quotactl
- (QCMD(Q_V1_SETQUOTA, h->qh_type), h->qh_quotadev, dquot->dq_id,
+ if (quotactl(QCMD(Q_V1_SETQUOTA, h->qh_type), h->qh_quotadev, dquot->dq_id,
(void *)&kdqblk) < 0)
return -1;
}
@@ -296,5 +310,5 @@ static int v1_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct d
}
if (!rd) /* EOF? */
return 0;
- return -1; /* Some read error... */
+ return -1; /* Some read errstr... */
}
diff --git a/quotaio_v2.c b/quotaio_v2.c
index ecbce1d..f256b3c 100644
--- a/quotaio_v2.c
+++ b/quotaio_v2.c
@@ -139,8 +139,8 @@ static int v2_init_io(struct quota_handle *h)
if (QIO_ENABLED(h)) {
struct v2_kern_dqinfo kdqinfo;
- if (quotactl(QCMD(Q_V2_GETINFO, h->qh_type), h->qh_quotadev, 0, (void *)&kdqinfo) <
- 0) return -1;
+ if (quotactl(QCMD(Q_V2_GETINFO, h->qh_type), h->qh_quotadev, 0, (void *)&kdqinfo) < 0)
+ return -1;
h->qh_info.dqi_bgrace = kdqinfo.dqi_bgrace;
h->qh_info.dqi_igrace = kdqinfo.dqi_igrace;
h->qh_info.u.v2_mdqi.dqi_flags = kdqinfo.dqi_flags;
@@ -194,6 +194,11 @@ static int v2_new_io(struct quota_handle *h)
*/
static int v2_write_info(struct quota_handle *h)
{
+ if (QIO_RO(h)) {
+ errstr(_("Trying to write info to readonly quotafile on %s\n"), h->qh_quotadev);
+ errno = EPERM;
+ return -1;
+ }
if (QIO_ENABLED(h)) {
struct v2_kern_dqinfo kdqinfo;
@@ -203,8 +208,8 @@ static int v2_write_info(struct quota_handle *h)
kdqinfo.dqi_blocks = h->qh_info.u.v2_mdqi.dqi_blocks;
kdqinfo.dqi_free_blk = h->qh_info.u.v2_mdqi.dqi_free_blk;
kdqinfo.dqi_free_entry = h->qh_info.u.v2_mdqi.dqi_free_entry;
- if (quotactl(QCMD(Q_V2_SETINFO, h->qh_type), h->qh_quotadev, 0, (void *)&kdqinfo) <
- 0) return -1;
+ if (quotactl(QCMD(Q_V2_SETINFO, h->qh_type), h->qh_quotadev, 0, (void *)&kdqinfo) < 0)
+ return -1;
}
else {
struct v2_disk_dqinfo ddqinfo;
@@ -261,7 +266,7 @@ static int get_free_dqblk(struct quota_handle *h)
memset(buf, 0, V2_DQBLKSIZE);
if (write_blk(h, info->dqi_blocks, buf) < 0) { /* Assure block allocation... */
freedqbuf(buf);
- fprintf(stderr, "Can't allocate new quota block (out of disk space).\n");
+ errstr(_("Can't allocate new quota block (out of disk space).\n"));
return -ENOSPC;
}
blk = info->dqi_blocks++;
@@ -570,7 +575,7 @@ static inline loff_t find_dqentry(struct quota_handle *h, struct dquot *dquot)
/*
* Read dquot (either from disk or from kernel)
- * User can use errno to detect error when NULL is returned
+ * User can use errno to detect errstr when NULL is returned
*/
static struct dquot *v2_read_dquot(struct quota_handle *h, qid_t id)
{
@@ -587,8 +592,7 @@ static struct dquot *v2_read_dquot(struct quota_handle *h, qid_t id)
if (QIO_ENABLED(h)) {
struct v2_kern_dqblk kdqblk;
- if (quotactl(QCMD(Q_V2_GETQUOTA, h->qh_type), h->qh_quotadev, id, (void *)&kdqblk) <
- 0) {
+ if (quotactl(QCMD(Q_V2_GETQUOTA, h->qh_type), h->qh_quotadev, id, (void *)&kdqblk) < 0) {
free(dquot);
return NULL;
}
@@ -613,20 +617,25 @@ static struct dquot *v2_read_dquot(struct quota_handle *h, qid_t id)
/*
* Commit changes of dquot to disk - it might also mean deleting it when quota became fake one and user has no blocks...
- * User can process use 'errno' to detect error
+ * User can process use 'errno' to detect errstr
*/
static int v2_commit_dquot(struct dquot *dquot)
{
struct util_dqblk *b = &dquot->dq_dqb;
+ if (QIO_RO(dquot->dq_h)) {
+ errstr(_("Trying to write quota to readonly quotafile on %s\n"), dquot->dq_h->qh_quotadev);
+ errno = EPERM;
+ return -1;
+ }
if (QIO_ENABLED(dquot->dq_h)) {
struct v2_kern_dqblk kdqblk;
v2_util2kerndqblk(&kdqblk, &dquot->dq_dqb);
- if (quotactl
- (QCMD(Q_V2_SETQUOTA, dquot->dq_h->qh_type), dquot->dq_h->qh_quotadev,
+ if (quotactl(QCMD(Q_V2_SETQUOTA, dquot->dq_h->qh_type), dquot->dq_h->qh_quotadev,
dquot->dq_id, (void *)&kdqblk) < 0)
return -1;
+ return 0;
}
if (!b->dqb_curspace && !b->dqb_curinodes && !b->dqb_bsoftlimit && !b->dqb_isoftlimit
&& !b->dqb_bhardlimit && !b->dqb_ihardlimit)
diff --git a/quotaon.8 b/quotaon.8
index c243763..51eb4c7 100644
--- a/quotaon.8
+++ b/quotaon.8
@@ -5,18 +5,18 @@ quotaon, quotaoff \- turn filesystem quotas on and off
.SH SYNOPSIS
.B /usr/sbin/quotaon
[
-.B \-vug
+.B \-vugf
]
.IR filesystem .\|.\|.
.br
.B /usr/sbin/quotaon
[
-.B \-avug
+.B \-avugf
]
.LP
.B /usr/sbin/quotaoff
[
-.B \-vugdo
+.B \-vug
]
[
.B \-x
@@ -26,7 +26,7 @@ quotaon, quotaoff \- turn filesystem quotas on and off
.br
.B /usr/sbin/quotaoff
[
-.B \-avugdo
+.B \-avug
]
.SH DESCRIPTION
.SS quotaon
@@ -76,9 +76,11 @@ have any disk quotas turned off.
.SS quotaon
.TP
.B \-a
-All filesystems in
+All automatically mounted (no
+.B noauto
+option) non-NFS filesystems in
.B /etc/fstab
-marked read-write with quotas will have their quotas turned on.
+with quotas will have their quotas turned on.
This is normally used at boot time to enable quotas.
.TP
.B \-v
@@ -89,6 +91,12 @@ Manipulate user quotas. This is the default.
.TP
.B \-g
Manipulate group quotas.
+.TP
+.B \-f
+Make
+.B quotaon
+behave like being called as
+.BR quotaoff .
.SS quotaoff
.TP
.B \-a
diff --git a/quotaon.c b/quotaon.c
index e6545d4..326ed51 100644
--- a/quotaon.c
+++ b/quotaon.c
@@ -34,12 +34,13 @@
#ident "$Copyright: (c) 1980, 1990 Regents of the University of California $"
#ident "$Copyright: All rights reserved. $"
-#ident "$Id: quotaon.c,v 1.3 2001/04/26 09:36:08 jkar8572 Exp $"
+#ident "$Id: quotaon.c,v 1.4 2001/05/02 09:32:22 jkar8572 Exp $"
/*
* Turn quota on/off for a filesystem.
*/
#include <stdio.h>
+#include <errno.h>
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
@@ -51,11 +52,12 @@ int gflag; /* operate on group quotas */
int uflag; /* operate on user quotas */
int vflag; /* verbose */
int kqf; /* kernel quota format */
+char *progname;
-static void usage(char *whoami)
+static void usage(void)
{
- fprintf(stderr, _("Usage:\n\t%s [-guv] [-x state] -a\n"), whoami);
- fprintf(stderr, _("\t%s [-guv] [-x state] filesys ...\n"), whoami);
+ errstr(_("Usage:\n\t%s [-guv] [-x state] -a\n"));
+ errstr(_("\t%s [-guv] [-x state] filesys ...\n"));
exit(1);
}
@@ -99,8 +101,8 @@ static int newstate(struct mntent *mnt, int offmode, int type, char *extra)
|| (!offmode && kern_quota_on(mnt_fsname, type, 1 << QF_XFS))))
ret = xfs_newstate(mnt, type, extra, flags);
else {
- extra = get_qf_name(mnt, type, kqf);
- statefunc = (kqf & (1 << QF_VFSV0)) ? v1_newstate : v2_newstate;
+ extra = get_qf_name(mnt, type, (kqf & (1 << QF_VFSV0)) ? QF_VFSV0 : QF_VFSOLD);
+ statefunc = (kqf & (1 << QF_VFSV0)) ? v2_newstate : v1_newstate;
ret = statefunc(mnt, type, extra, flags);
free(extra);
}
@@ -112,16 +114,16 @@ int main(int argc, char **argv)
FILE *fp;
struct mntent *mnt;
long argnum, done = 0;
- char *whoami, *xarg = NULL;
+ char *xarg = NULL;
int c, offmode = 0, errs = 0;
gettexton();
- whoami = basename(argv[0]);
- if (strcmp(whoami, "quotaoff") == 0)
+ progname = basename(argv[0]);
+ if (strcmp(progname, "quotaoff") == 0)
offmode++;
- else if (strcmp(whoami, "quotaon") != 0)
- die(1, _("Name must be quotaon or quotaoff not %s\n"), whoami);
+ else if (strcmp(progname, "quotaon") != 0)
+ die(1, _("Name must be quotaon or quotaoff not %s\n"), progname);
while ((c = getopt(argc, argv, "afvugx:V")) != -1) {
switch (c) {
@@ -147,14 +149,14 @@ int main(int argc, char **argv)
version();
exit(0);
default:
- usage(whoami);
+ usage();
}
}
argc -= optind;
argv += optind;
if (argc <= 0 && !aflag)
- usage(whoami);
+ usage();
if (!gflag && !uflag) {
gflag++;
uflag++;
@@ -165,7 +167,7 @@ int main(int argc, char **argv)
fp = setmntent(MNTTAB, "r");
while ((mnt = getmntent(fp))) {
if (aflag) {
- if (hasmntopt(mnt, MNTOPT_NOAUTO))
+ if (hasmntopt(mnt, MNTOPT_NOAUTO) || !strcmp(mnt->mnt_type, MNTTYPE_NFS))
continue;
}
else {
@@ -174,6 +176,10 @@ int main(int argc, char **argv)
else
continue;
}
+ if (!strcmp(mnt->mnt_type, MNTTYPE_NFS)) {
+ fprintf(stderr, "%s: Quota can't be turned on on NFS filesystem\n", mnt->mnt_fsname);
+ continue;
+ }
if (gflag)
errs += newstate(mnt, offmode, GRPQUOTA, xarg);
@@ -184,7 +190,7 @@ int main(int argc, char **argv)
for (c = 0; c < argc; c++)
if ((done & (1 << c)) == 0)
- fprintf(stderr, _("%s not found in fstab\n"), argv[c]);
+ errstr(_("%s not found in fstab\n"), argv[c]);
return errs;
}
@@ -197,9 +203,8 @@ static int quotaonoff(char *quotadev, char *quotafile, int type, int flags)
if (flags & STATEFLAG_OFF) {
qcmd = QCMD(Q_QUOTAOFF, type);
- if (quotactl(qcmd, quotadev, 0, (void *)0) < 0) {
- fprintf(stderr, "quotaoff: ");
- perror(quotadev);
+ if (quotactl(qcmd, quotadev, 0, NULL) < 0) {
+ errstr(_("quotactl on %s: %s\n"), quotadev, strerror(errno));
return 1;
}
if (flags & STATEFLAG_VERBOSE)
@@ -208,8 +213,7 @@ static int quotaonoff(char *quotadev, char *quotafile, int type, int flags)
}
qcmd = QCMD(Q_QUOTAON, type);
if (quotactl(qcmd, quotadev, 0, (void *)quotafile) < 0) {
- fprintf(stderr, _("quotaon: using %s on "), quotafile);
- perror(quotadev);
+ errstr(_("using %s on %s: %s\n"), quotafile, quotadev, strerror(errno));
return 1;
}
if (flags & STATEFLAG_VERBOSE)
@@ -227,8 +231,7 @@ static int quotarsquashonoff(const char *quotadev, int type, int flags)
int qcmd = QCMD(Q_V1_RSQUASH, type);
if (quotactl(qcmd, quotadev, 0, (void *)&mode) < 0) {
- fprintf(stderr, _("quotaon: set root_squash on"));
- perror(quotadev);
+ errstr(_("set root_squash on %s: %s\n"), quotadev, strerror(errno));
return 1;
}
if ((flags & STATEFLAG_VERBOSE) && (flags & STATEFLAG_OFF))
@@ -265,12 +268,12 @@ int v1_newstate(struct mntent *mnt, int type, char *file, int flags)
int v2_newstate(struct mntent *mnt, int type, char *file, int flags)
{
const char *dev = get_device_name(mnt->mnt_fsname);
- int err = 1;
+ int errs = 0;
if (!dev)
- return err;
+ return 1;
if (hasquota(mnt, type))
- err = quotaonoff((char *)dev, file, type, flags);
+ errs = quotaonoff((char *)dev, file, type, flags);
free((char *)dev);
- return err;
+ return errs;
}
diff --git a/quotaon_xfs.c b/quotaon_xfs.c
index 4252fcf..f9d1918 100644
--- a/quotaon_xfs.c
+++ b/quotaon_xfs.c
@@ -31,8 +31,7 @@ static int xfs_state_check(int qcmd, int type, int flags, char *dev, int root, i
return 0; /* noop */
if (quotactl(QCMD(Q_XFS_GETQSTAT, 0), dev, 0, (void *)&info) < 0) {
- fprintf(stderr, flags & STATEFLAG_ON ? "quotaon: " : "quotaoff: ");
- perror(dev);
+ errstr(_("quotactl() on %s: %s\n"), dev, strerror(errno));
return -1;
}
@@ -64,7 +63,7 @@ static int xfs_state_check(int qcmd, int type, int flags, char *dev, int root, i
" (reboot to take effect)\n"), type2name(type));
return 1;
}
- fprintf(stderr, _("Enable XFS %s quota during mount\n"),
+ errstr(_("Enable XFS %s quota during mount\n"),
type2name(type));
return -1;
case Q_XFS_QUOTAOFF:
@@ -74,7 +73,7 @@ static int xfs_state_check(int qcmd, int type, int flags, char *dev, int root, i
case ACCT:
switch (qcmd) {
case Q_XFS_QUOTARM:
- fprintf(stderr, _("Cannot delete %s quota on %s - "
+ errstr(_("Cannot delete %s quota on %s - "
"switch quota accounting off first\n"),
type2name(type), dev);
return -1;
@@ -100,12 +99,12 @@ static int xfs_state_check(int qcmd, int type, int flags, char *dev, int root, i
case ENFD:
switch (qcmd) {
case Q_XFS_QUOTARM:
- fprintf(stderr, _("Cannot delete %s quota on %s - "
+ errstr(_("Cannot delete %s quota on %s - "
"switch quota enforcement off first\n"),
type2name(type), dev);
return -1;
case Q_XFS_QUOTAON:
- fprintf(stderr, _("Enforcing %s quota already on %s\n"),
+ errstr(_("Enforcing %s quota already on %s\n"),
type2name(type), dev);
return -1;
case Q_XFS_QUOTAOFF:
@@ -116,7 +115,7 @@ static int xfs_state_check(int qcmd, int type, int flags, char *dev, int root, i
}
break;
}
- fprintf(stderr, _("Unexpected XFS quota state sought on %s\n"), dev);
+ errstr(_("Unexpected XFS quota state sought on %s\n"), dev);
return -1;
}
@@ -131,8 +130,7 @@ static int xfs_onoff(char *dev, int type, int flags, int rootfs, int *xopts)
return (check < 0);
if (quotactl(QCMD(qcmd, type), dev, 0, (void *)xopts) < 0) {
- fprintf(stderr, qoff ? "quotaoff: " : "quotaon: ");
- perror(dev);
+ errstr(_("quotactl on %s: %s\n"), dev, strerror(errno));
return 1;
}
if ((flags & STATEFLAG_VERBOSE) && qoff)
@@ -152,8 +150,8 @@ 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) {
- fprintf(stderr, _("Failed to delete quota: "));
- perror(dev);
+ errstr(_("Failed to delete quota: %s"),
+ strerror(errno));
return 1;
}
diff --git a/quotaops.c b/quotaops.c
index 15bd2a8..b9cd873 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.3 2001/04/12 05:56:53 jkar8572 Exp $"
+#ident "$Id: quotaops.c,v 1.4 2001/05/02 09:32:22 jkar8572 Exp $"
#include <rpc/rpc.h>
#include <sys/types.h>
@@ -76,7 +76,7 @@ static int cvtatos(time_t time, char *units, time_t * seconds)
else if (memcmp(units, "day", 3) == 0)
*seconds = time * 24 * 60 * 60;
else {
- fprintf(stderr, _("%s: bad units, specify:\n %s, %s, %s, or %s"), units,
+ errstr(_("bad units, specify:\n %s, %s, %s, or %s"), units,
"days", "hours", "minutes", "seconds");
return -1;
}
@@ -90,10 +90,48 @@ struct dquot *getprivs(qid_t id, struct quota_handle **handles)
{
struct dquot *q, *qtail = NULL, *qhead = NULL;
int i;
+#if defined(BSD_BEHAVIOUR)
+ int j, ngroups;
+ uid_t euid;
+ gid_t gidset[NGROUPS];
+ char name[MAXNAMELEN];
+#endif
for (i = 0; handles[i]; i++) {
+#if defined(BSD_BEHAVIOUR)
+ switch (handles[i]->qh_type) {
+ case USRQUOTA:
+ euid = geteuid();
+ if (euid != id && euid != 0) {
+ uid2user(id, name);
+ die(1, _("%s (uid %d): permission denied\n"), name, id);
+ }
+ break;
+ case GRPQUOTA:
+ ngroups = getgroups(NGROUPS, gidset);
+ if (ngroups < 0) {
+ die(1, _("Error while trying getgroups(): %s\n"), strerror(errno));
+ continue;
+ }
+
+ for (j = 0; j < ngroups; j++)
+ if (id == gidset[j])
+ break;
+
+ if (j >= ngroups && geteuid() != 0) {
+ gid2group(id, name);
+ errstr(_("%s (gid %d): permission denied\n"),
+ name, id);
+ return (struct dquot *)NULL;
+ }
+ break;
+ default:
+ break;
+ }
+#endif
+
if (!(q = handles[i]->qh_ops->read_dquot(handles[i], id))) {
- fprintf(stderr, _("Error while getting quota from %s for %u: %s\n"),
+ errstr(_("Error while getting quota from %s for %u: %s\n"),
handles[i]->qh_quotadev, id, strerror(errno));
continue;
}
@@ -116,8 +154,8 @@ int putprivs(struct dquot *qlist)
for (q = qlist; q; q = q->dq_next) {
if (q->dq_h->qh_ops->commit_dquot(q) == -1) {
- fprintf(stderr, _("Can't write quota for %u on %s: %s\n"), q->dq_id,
- q->dq_h->qh_quotadev, strerror(errno));
+ errstr(_("Can't write quota for %u on %s: %s\n"),
+ q->dq_id, q->dq_h->qh_quotadev, strerror(errno));
continue;
}
}
@@ -129,10 +167,15 @@ int putprivs(struct dquot *qlist)
*/
int editprivs(char *tmpfile)
{
- long omask;
- int pid, stat;
-
- omask = sigblock(sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGHUP));
+ sigset_t omask, nmask;
+ pid_t pid;
+ int stat;
+
+ sigemptyset(&nmask);
+ sigaddset(&nmask, SIGINT);
+ sigaddset(&nmask, SIGQUIT);
+ sigaddset(&nmask, SIGHUP);
+ sigprocmask(SIG_SETMASK, &nmask, &omask);
if ((pid = fork()) < 0) {
perror("fork");
return -1;
@@ -140,7 +183,7 @@ int editprivs(char *tmpfile)
if (pid == 0) {
char *ed;
- sigsetmask(omask);
+ sigprocmask(SIG_SETMASK, &omask, NULL);
setgid(getgid());
setuid(getuid());
if ((ed = getenv("VISUAL")) == (char *)0)
@@ -150,7 +193,7 @@ int editprivs(char *tmpfile)
die(1, _("Can't exec %s\n"), ed);
}
waitpid(pid, &stat, 0);
- sigsetmask(omask);
+ sigprocmask(SIG_SETMASK, &omask, NULL);
return 0;
}
@@ -188,7 +231,7 @@ int writeprivs(struct dquot *qlist, int outfd, char *name, int quotatype)
#else
fprintf(fd, _("Quotas for %s %s:\n"), type2name(quotatype), name);
for (q = qlist; q; q = q->dq_next) {
- fprintf(fd, _("%s: %s %d, limits (soft = %d, hard = %d)\n"),
+ fprintf(fd, _("%s %d, limits (soft = %d, hard = %d)\n"),
q->dq_h->qh_quotadev, _("blocks in use:"),
(int)toqb(q->dq_dqb.dqb_curspace),
q->dq_dqb.dqb_bsoftlimit, q->dq_dqb.dqb_bhardlimit);
@@ -233,10 +276,10 @@ static void merge_to_list(struct dquot *qlist, char *dev, u_int64_t blocks, u_in
q->dq_flags |= DQ_FOUND;
if (blocks != toqb(q->dq_dqb.dqb_curspace))
- fprintf(stderr, _("WARNING: %s: cannot change current block allocation\n"),
+ errstr(_("WARNING - %s: cannot change current block allocation\n"),
q->dq_h->qh_quotadev);
if (inodes != q->dq_dqb.dqb_curinodes)
- fprintf(stderr, _("WARNING: %s: cannot change current inode allocation\n"),
+ errstr(_("WARNING - %s: cannot change current inode allocation\n"),
q->dq_h->qh_quotadev);
}
}
@@ -273,7 +316,7 @@ int readprivs(struct dquot *qlist, int infd)
fsp, &blocks, &bsoft, &bhard, &inodes, &isoft, &ihard);
if (cnt != 7) {
- fprintf(stderr, _("Bad format:\n%s\n"), line);
+ errstr(_("Bad format:\n%s\n"), line);
return -1;
}
@@ -286,30 +329,34 @@ int readprivs(struct dquot *qlist, int infd)
fgets(line1, sizeof(line1), fd);
while (fgets(line1, sizeof(line1), fd) && fgets(line2, sizeof(line2), fd)) {
if (!(fsp = strtok(line1, " \t:"))) {
- fprintf(stderr, _("%s: bad format\n"), line1);
+ errstr(_("%s - bad format\n"), line1);
return -1;
}
if (!(cp = strtok(NULL, "\n"))) {
- fprintf(stderr, _("%s: %s: bad format\n"), fsp, &fsp[strlen(fsp) + 1]);
+ errstr(_("%s - %s -- bad format\n"),
+ fsp, &fsp[strlen(fsp) + 1]);
return -1;
}
cnt = sscanf(cp, _(" blocks in use: %Lu, limits (soft = %Lu, hard = %Lu)"),
&blocks, &bsoft, &bhard);
if (cnt != 3) {
- fprintf(stderr, _("%s:%s: bad format\n"), fsp, cp);
+ errstr(_("%s - %s -- bad format\n"),
+ fsp, cp);
return -1;
}
if (!(cp = strtok(line2, "\n"))) {
- fprintf(stderr, _("%s: %s: bad format\n"), fsp, line2);
+ errstr(_("%s - %s -- bad format\n"),
+ fsp, line2);
return -1;
}
cnt = sscanf(cp, _("\tinodes in use: %Lu, limits (soft = %Lu, hard = %Lu)"),
&inodes, &isoft, &ihard);
if (cnt != 3) {
- fprintf(stderr, _("%s: %s: bad format\n"), fsp, line2);
+ errstr(_("%s - %s -- bad format\n"),
+ fsp, line2);
return -1;
}
@@ -369,7 +416,7 @@ int writetimes(struct quota_handle **handles, int outfd)
for (i = 0; handles[i]; i++) {
time2str(handles[i]->qh_info.dqi_bgrace, btimebuf, 0);
time2str(handles[i]->qh_info.dqi_igrace, itimebuf, 0);
- fprintf(fd, _("%s: block grace period: %s, file grace period: %s\n"),
+ fprintf(fd, _("block grace period: %s, file grace period: %s\n"),
handles[i]->qh_quotadev, btimebuf, itimebuf);
}
#endif
@@ -397,7 +444,8 @@ int readtimes(struct quota_handle **handles, int infd)
return 0;
lseek(infd, 0, SEEK_SET);
if (!(fd = fdopen(dup(infd), "r"))) {
- fprintf(stderr, _("Can't reopen temp file: %s\n"), strerror(errno));
+ errstr(_("Can't reopen temp file: %s\n"),
+ strerror(errno));
return -1;
}
@@ -418,7 +466,7 @@ int readtimes(struct quota_handle **handles, int infd)
while (fgets(line, sizeof(line), fd)) {
cnt = sscanf(line, "%s %d %s %d %s", fsp, &btime, bunits, &itime, iunits);
if (cnt != 5) {
- fprintf(stderr, _("bad format:\n%s\n"), line);
+ errstr(_("bad format:\n%s\n"), line);
return -1;
}
#else
@@ -430,17 +478,19 @@ int readtimes(struct quota_handle **handles, int infd)
while (fgets(line1, sizeof(line1), fd)) {
if (!(fsp = strtok(line1, " \t:"))) {
- fprintf(stderr, _("%s: bad format\n"), line1);
+ errstr(_("%s - bad format\n"), line1);
return -1;
}
if (!(cp = strtok(NULL, "\n"))) {
- fprintf(stderr, _("%s: %s: bad format\n"), fsp, &fsp[strlen(fsp) + 1]);
+ errstr(_("%s - %s -- bad format\n"),
+ fsp, &fsp[strlen(fsp) + 1]);
return -1;
}
cnt = sscanf(cp, _(" block grace period: %d %s file grace period: %d %s"),
&btime, bunits, &itime, iunits);
if (cnt != 4) {
- fprintf(stderr, _("%s:%s: bad format\n"), fsp, cp);
+ errstr(_("%s - %s -- bad format\n"),
+ fsp, cp);
return -1;
}
#endif
diff --git a/quotastats.c b/quotastats.c
index 6b67222..522f6a6 100644
--- a/quotastats.c
+++ b/quotastats.c
@@ -10,7 +10,7 @@
*
* Author: Marco van Wieringen <mvw@planets.elm.net>
*
- * Version: $Id: quotastats.c,v 1.1 2001/03/23 12:03:27 jkar8572 Exp $
+ * Version: $Id: quotastats.c,v 1.2 2001/05/02 09:32:22 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
@@ -27,7 +27,7 @@
static inline int get_stats(struct dqstats *dqstats)
{
- return quotactl(QCMD(Q_GETSTATS, 0), (char *)NULL, 0, (caddr_t) dqstats);
+ return quotactl(QCMD(Q_GETSTATS, 0), (char *)NULL, 0, (caddr_t)dqstats);
}
static inline int print_stats(struct dqstats *dqstats)
diff --git a/quotasys.c b/quotasys.c
index b2dd507..300ac55 100644
--- a/quotasys.c
+++ b/quotasys.c
@@ -62,7 +62,7 @@ uid_t user2uid(char *name)
if (!*errch) /* Is name number - we got directly uid? */
return ret;
if (!(entry = getpwnam(name))) {
- fprintf(stderr, _("User %s doesn't exist.\n"), name);
+ errstr(_("User %s doesn't exist.\n"), name);
exit(1);
}
return entry->pw_uid;
@@ -81,7 +81,7 @@ gid_t group2gid(char *name)
if (!*errch) /* Is name number - we got directly gid? */
return ret;
if (!(entry = getgrnam(name))) {
- fprintf(stderr, _("Group %s doesn't exist.\n"), name);
+ errstr(_("Group %s doesn't exist.\n"), name);
exit(1);
}
return entry->gr_gid;
@@ -106,7 +106,7 @@ void uid2user(uid_t id, char *buf)
struct passwd *entry;
if (!(entry = getpwuid(id)))
- sprintf(buf, "#%u", (uint) id);
+ snprintf(buf, MAXNAMELEN, "#%u", (uint) id);
else
sstrncpy(buf, entry->pw_name, MAXNAMELEN);
}
@@ -119,7 +119,7 @@ void gid2group(gid_t id, char *buf)
struct group *entry;
if (!(entry = getgrgid(id)))
- sprintf(buf, "#%u", (uint) id);
+ snprintf(buf, MAXNAMELEN, "#%u", (uint) id);
else
sstrncpy(buf, entry->gr_name, MAXNAMELEN);
}
@@ -145,7 +145,7 @@ int name2fmt(char *str)
for (fmt = 0; fmt < QUOTAFORMATS; fmt++)
if (!strcmp(str, fmtnames[fmt]))
return fmt;
- fprintf(stderr, _("Unknown quota format: %s\nSupported formats are:\n\
+ errstr(_("Unknown quota format: %s\nSupported formats are:\n\
vfsold - original quota format\n\
vfsv0 - new quota format\n\
rpc - use RPC calls\n\
@@ -196,17 +196,17 @@ void time2str(time_t seconds, char *buf, int flags)
hours %= 24;
if (flags & TF_ROUND) {
if (days >= 2)
- sprintf(buf, _("%ddays"), days);
+ snprintf(buf, MAXTIMELEN, _("%ddays"), days);
else
- sprintf(buf, _("%02d:%02d"), hours + days * 24, minutes);
+ snprintf(buf, MAXTIMELEN, _("%02d:%02d"), hours + days * 24, minutes);
}
else {
if (minutes || (!minutes && !hours && !days))
- sprintf(buf, _("%uminutes"), (uint) (seconds + 30) / 60);
+ snprintf(buf, MAXTIMELEN, _("%uminutes"), (uint) (seconds + 30) / 60);
else if (hours)
- sprintf(buf, _("%uhours"), hours + days * 24);
+ snprintf(buf, MAXTIMELEN, _("%uhours"), hours + days * 24);
else
- sprintf(buf, _("%udays"), days);
+ snprintf(buf, MAXTIMELEN, _("%udays"), days);
}
}
@@ -271,11 +271,12 @@ static int check_fmtfile_exists(struct mntent *mnt, int type, int fmt, char *nam
{
struct stat buf;
- sprintf(namebuf, "%s/%s.%s", mnt->mnt_dir, basenames[fmt], extensions[type]);
+ snprintf(namebuf, PATH_MAX, "%s/%s.%s", mnt->mnt_dir, basenames[fmt], extensions[type]);
if (!stat(namebuf, &buf))
return 1;
if (errno != ENOENT) {
- fprintf(stderr, _("Can't stat quotafile %s: %s\n"), namebuf, strerror(errno));
+ errstr(_("Can't stat quotafile %s: %s\n"),
+ namebuf, strerror(errno));
return -1;
}
return 0;
@@ -328,7 +329,7 @@ char *get_qf_name(struct mntent *mnt, int type, int fmt)
return NULL;
}
else if (basenames[fmt][0]) /* Any name specified? */
- sprintf(qfullname, "%s/%s.%s", mnt->mnt_dir, basenames[fmt], extensions[type]);
+ snprintf(qfullname, PATH_MAX, "%s/%s.%s", mnt->mnt_dir, basenames[fmt], extensions[type]);
return sstrdup(qfullname);
}
@@ -338,7 +339,7 @@ char *get_qf_name(struct mntent *mnt, int type, int fmt)
* List of zero length means scan all entries in /etc/mtab
*/
struct quota_handle **create_handle_list(int count, char **mntpoints, int type, int fmt,
- char local_only)
+ int flags)
{
FILE *mntf;
struct mntent *mnt;
@@ -365,16 +366,16 @@ struct quota_handle **create_handle_list(int count, char **mntpoints, int type,
if (gotmnt == MAXMNTPOINTS)
die(3, _("Too many mountpoints. Please report to: %s\n"),
MY_EMAIL);
- if (!(hlist[gotmnt] = init_io(mnt, type, fmt)))
+ if (!(hlist[gotmnt] = init_io(mnt, type, fmt, flags)))
continue;
gotmnt++;
}
- else if (!local_only && (fmt == -1 || fmt == QF_RPC)) { /* Use NFS? */
+ 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)))
+ if (!(hlist[gotmnt] = init_io(mnt, type, fmt, flags)))
continue;
gotmnt++;
#endif
@@ -393,11 +394,11 @@ struct quota_handle **create_handle_list(int count, char **mntpoints, int type,
*/
int dispose_handle_list(struct quota_handle **hlist)
{
- int i, ret;
+ int i;
for (i = 0; hlist[i]; i++)
- if ((ret = end_io(hlist[i])))
- fprintf(stderr, _("Error while releasing file on %s\n"),
+ if (end_io(hlist[i]) < 0)
+ errstr(_("Error while releasing file on %s\n"),
hlist[i]->qh_quotadev);
return 0;
}
@@ -463,17 +464,17 @@ int kern_quota_format(void)
void warn_new_kernel(int fmt)
{
if (fmt == -1 && kern_quota_format() == QF_TOONEW)
- fprintf(stderr,
- _
- ("Warning: Kernel quota is newer than supported. Quotafile used by utils need not be the one used by kernel.\n"));
+ errstr(
+ _("WARNING - Kernel quota is newer than supported. Quotafile used by utils need not be the one used by kernel.\n"));
}
/* Check whether old quota is turned on on given device */
static int v1_kern_quota_on(const char *dev, int type)
{
char tmp[1024]; /* Just temporary buffer */
+ qid_t id = (type == USRQUOTA) ? getuid() : getgid();
- if (!quotactl(QCMD(Q_V1_GETQUOTA, type), dev, 0, tmp)) /* OK? */
+ if (!quotactl(QCMD(Q_V1_GETQUOTA, type), dev, id, tmp)) /* OK? */
return 1;
return 0;
}
@@ -482,8 +483,9 @@ static int v1_kern_quota_on(const char *dev, int type)
static int v2_kern_quota_on(const char *dev, int type)
{
char tmp[1024]; /* Just temporary buffer */
+ qid_t id = (type == USRQUOTA) ? getuid() : getgid();
- if (!quotactl(QCMD(Q_V2_GETINFO, type), dev, 0, tmp)) /* OK? */
+ if (!quotactl(QCMD(Q_V2_GETQUOTA, type), dev, id, tmp)) /* OK? */
return 1;
return 0;
}
diff --git a/quotasys.h b/quotasys.h
index daeaeee..48544e5 100644
--- a/quotasys.h
+++ b/quotasys.h
@@ -17,6 +17,11 @@
/* Flags for formatting time */
#define TF_ROUND 0x1 /* Should be printed time rounded? */
+/* Flags for IO initialization */
+#define IOI_LOCALONLY 0x1 /* Operate only on local quota */
+#define IOI_READONLY 0x2 /* Only readonly access */
+#define IOI_OPENFILE 0x4 /* Open file even if kernel has quotas turned on */
+
/*
* Exported functions
*/
@@ -61,8 +66,7 @@ char *get_qf_name(struct mntent *mnt, int type, int fmt);
/* Create NULL-terminated list of handles for quotafiles for given mountpoints */
struct quota_handle **create_handle_list(int count, char **mntpoints, int type, int fmt,
-
- char local_only);
+ int flags);
/* Dispose given list of handles */
int dispose_handle_list(struct quota_handle **hlist);
diff --git a/repquota.8 b/repquota.8
index a4f5854..f3d5daf 100644
--- a/repquota.8
+++ b/repquota.8
@@ -6,12 +6,18 @@ repquota \- summarize quotas for a filesystem
.B /usr/etc/repquota
[
.B \-vug
+] [
+.B \-F
+.I format-name
]
.IR filesystem .\|.\|.
.LP
.B /usr/etc/repquota
[
.B \-avug
+] [
+.B \-F
+.I format-name
]
.SH DESCRIPTION
.IX "repquota command" "" "\fLrepquota\fP \(em summarize quotas"
@@ -36,7 +42,20 @@ Report on all filesystems indicated in
to be read-write with quotas.
.TP
.B \-v
-Report all quotas, even if there is no usage.
+Report all quotas, even if there is no usage. Be also more verbose about quotafile
+information.
+.TP
+.B \-F \f2format-name\f1
+Report quota for specified format (ie. don't perform format autodetection).
+Possible format names are:
+.B vfsold
+(version 1 quota),
+.B vfsv0
+(version 2 quota),
+.B rpc
+(quota over NFS),
+.B xfs
+(quota on XFS filesystem)
.TP
.B \-g
Report quotas for groups.
diff --git a/repquota.c b/repquota.c
index 0399167..0ef7086 100644
--- a/repquota.c
+++ b/repquota.c
@@ -27,6 +27,14 @@
int flags, fmt = -1;
char **mnt;
int mntcnt;
+char *progname;
+
+static void usage()
+{
+ errstr(_("Utility for reporting quotas.\nUsage:\n%s [-vug] [-F quotaformat] (-a | mntpoint)\n"), progname);
+ errstr(_("Bugs to %s\n"), MY_EMAIL);
+ exit(1);
+}
static void parse_options(int argcnt, char **argstr)
{
@@ -42,10 +50,7 @@ static void parse_options(int argcnt, char **argstr)
switch (ret) {
case '?':
case 'h':
- usage:
- fprintf(stderr, _("Utility for reporting quotas.\nUsage:\n%s [-vug] [-F quotaformat] (-a | mntpoint)\n"), slash);
- fprintf(stderr, _("Bugs to %s\n"), MY_EMAIL);
- exit(1);
+ usage();
case 'V':
version();
exit(0);
@@ -71,7 +76,7 @@ static void parse_options(int argcnt, char **argstr)
if ((flags & FL_ALL && optind != argcnt) || (!(flags & FL_ALL) && optind == argcnt)) {
fputs(_("Bad number of arguments.\n"), stderr);
- goto usage;
+ usage();
}
if (fmt == QF_RPC) {
fputs(_("Repquota can't report through RPC calls.\n"), stderr);
@@ -142,22 +147,27 @@ static void report(int type)
int i;
if (flags & FL_ALL)
- handles = create_handle_list(0, NULL, type, fmt, 1);
+ handles = create_handle_list(0, NULL, type, fmt, IOI_LOCALONLY | IOI_READONLY | IOI_OPENFILE);
else
- handles = create_handle_list(mntcnt, mnt, type, fmt, 1);
+ handles = create_handle_list(mntcnt, mnt, type, fmt, IOI_LOCALONLY | IOI_READONLY | IOI_OPENFILE);
for (i = 0; handles[i]; i++)
report_it(handles[i], type);
dispose_handle_list(handles);
}
-int main(int argcnt, char **argstr)
+int main(int argc, char **argv)
{
gettexton();
- parse_options(argcnt, argstr);
+ progname = basename(argv[0]);
+
+ parse_options(argc, argv);
warn_new_kernel(fmt);
+
if (flags & FL_USER)
report(USRQUOTA);
+
if (flags & FL_GROUP)
report(GRPQUOTA);
+
return 0;
}
diff --git a/rquota_server.c b/rquota_server.c
index 7468661..caa1327 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.1 2001/03/23 12:03:27 jkar8572 Exp $
+ * Version: $Id: rquota_server.c,v 1.2 2001/05/02 09:32:22 jkar8572 Exp $
*
* Author: Marco van Wieringen <mvw@planets.elm.net>
*
@@ -177,7 +177,7 @@ setquota_rslt *setquotainfo(int flags, caddr_t * argp, struct svc_req *rqstp)
continue;
if (st.st_dev != device)
continue;
- if (!(handles[0] = init_io(mnt, type, -1)))
+ if (!(handles[0] = init_io(mnt, type, -1, 0)))
continue;
break;
}
@@ -281,7 +281,7 @@ getquota_rslt *getquotainfo(int flags, caddr_t * argp, struct svc_req * rqstp)
continue;
if (st.st_dev != device)
continue;
- if (!(handles[0] = init_io(mnt, type, -1)))
+ if (!(handles[0] = init_io(mnt, type, -1, IOI_READONLY)))
continue;
break;
}
diff --git a/rquota_svc.c b/rquota_svc.c
index 368d212..6baf0a3 100644
--- a/rquota_svc.c
+++ b/rquota_svc.c
@@ -1,8 +1,23 @@
/*
- * Please do not edit this file.
- * It was generated using rpcgen.
+ * QUOTA An implementation of the diskquota system for the LINUX operating
+ * system. QUOTA is implemented using the BSD systemcall interface
+ * as the means of communication with the user level. Should work for
+ * all filesystems because of integration into the VFS layer of the
+ * operating system. This is based on the Melbourne quota system wich
+ * uses both user and group quota files.
+ *
+ * Rquota service handlers.
+ *
+ * Author: Marco van Wieringen <mvw@planets.elm.net>
+ *
+ * Version: $Id: rquota_svc.c,v 1.2 2001/05/02 09:32:22 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
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
*/
-
+
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -18,9 +33,12 @@
#endif
#include "pot.h"
+#include "common.h"
#include "rquota.h"
#include "quotasys.h"
+char *progname;
+
/*
* Global authentication credentials.
*/
@@ -100,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)) {
- fprintf(stderr, _("unable to free arguments"));
+ errstr(_("unable to free arguments"));
exit(1);
}
return;
@@ -178,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)) {
- fprintf(stderr, _("unable to free arguments"));
+ errstr(_("unable to free arguments"));
exit(1);
}
return;
@@ -192,6 +210,8 @@ int main(int argc, char **argv)
argvargs = argv;
gettexton();
+ progname = basename(argv[0]);
+
warn_new_kernel(-1);
(void)pmap_unset(RQUOTAPROG, RQUOTAVERS);
@@ -199,35 +219,35 @@ int main(int argc, char **argv)
transp = svcudp_create(RPC_ANYSOCK);
if (transp == NULL) {
- fprintf(stderr, _("cannot create udp service."));
+ errstr(_("cannot create udp service."));
exit(1);
}
if (!svc_register(transp, RQUOTAPROG, RQUOTAVERS, rquotaprog_1, IPPROTO_UDP)) {
- fprintf(stderr, _("unable to register (RQUOTAPROG, RQUOTAVERS, udp)."));
+ errstr(_("unable to register (RQUOTAPROG, RQUOTAVERS, udp)."));
exit(1);
}
if (!svc_register(transp, RQUOTAPROG, EXT_RQUOTAVERS, rquotaprog_2, IPPROTO_UDP)) {
- fprintf(stderr, _("unable to register (RQUOTAPROG, EXT_RQUOTAVERS, udp)."));
+ errstr(_("unable to register (RQUOTAPROG, EXT_RQUOTAVERS, udp)."));
exit(1);
}
transp = svctcp_create(RPC_ANYSOCK, 0, 0);
if (transp == NULL) {
- fprintf(stderr, _("cannot create tcp service."));
+ errstr(_("cannot create tcp service."));
exit(1);
}
if (!svc_register(transp, RQUOTAPROG, RQUOTAVERS, rquotaprog_1, IPPROTO_TCP)) {
- fprintf(stderr, _("unable to register (RQUOTAPROG, RQUOTAVERS, tcp)."));
+ errstr(_("unable to register (RQUOTAPROG, RQUOTAVERS, tcp)."));
exit(1);
}
if (!svc_register(transp, RQUOTAPROG, EXT_RQUOTAVERS, rquotaprog_2, IPPROTO_TCP)) {
- fprintf(stderr, _("unable to register (RQUOTAPROG, EXT_RQUOTAVERS, tcp)."));
+ errstr(_("unable to register (RQUOTAPROG, EXT_RQUOTAVERS, tcp)."));
exit(1);
}
daemon(1, 1);
svc_run();
- fprintf(stderr, _("svc_run returned"));
+ errstr(_("svc_run returned"));
exit(1);
/* NOTREACHED */
}
diff --git a/rquotad.8 b/rquotad.8
index e6bbb1e..8952f06 100644
--- a/rquotad.8
+++ b/rquotad.8
@@ -18,9 +18,13 @@ is an
server which returns quotas for a user of a local filesystem
which is mounted by a remote machine over the
.SM NFS\s0.
-The results are used by
+It also allows setting of quotas on
+.SM NFS
+mounted filesystem. The results are used by
.BR quota (1)
-to display user quotas for remote filesystems.
+to display user quotas for remote filesystems and by
+.BR edquota (8)
+to set quotas on remote filesystems.
The
.B rquotad
daemon is normally started at boot time from the
diff --git a/set_limits_example.c b/set_limits_example.c
index 52af20c..d437604 100644
--- a/set_limits_example.c
+++ b/set_limits_example.c
@@ -14,15 +14,14 @@ int copy_user_quota_limits(const char *block_device, uid_t from, uid_t to)
return (0);
}
else {
- fprintf(stderr,
- _
- ("copy_user_quota_limits: Failed to set userquota for uid %ld : %s\n"),
+ errstr(
+ _("copy_user_quota_limits: Failed to set userquota for uid %ld : %s\n"),
to, strerror(errno));
return (1);
}
}
else {
- fprintf(stderr,
+ errstr(
_("copy_user_quota_limits: Failed to get userquota for uid %ld : %s\n"),
from, strerror(errno));
return (1);
@@ -38,15 +37,14 @@ int copy_group_quota_limits(const char *block_device, gid_t from, gid_t to)
return (0);
}
else {
- fprintf(stderr,
- _
- ("copy_group_quota_limits: Failed to set groupquota for uid %ld : %s\n"),
+ errstr(
+ _("copy_group_quota_limits: Failed to set groupquota for uid %ld : %s\n"),
to, strerror(errno));
return (1);
}
}
else {
- fprintf(stderr,
+ errstr(
_("copy_group_quota_limits: Failed to get groupquota for uid %ld : %s\n"),
from, strerror(errno));
return (1);
diff --git a/setquota.8 b/setquota.8
index 6f65dbd..5177da1 100644
--- a/setquota.8
+++ b/setquota.8
@@ -22,7 +22,7 @@ setquota \- set disk quotas
.I inode-hardlimit
.B \-a
|
-.I filesystem
+.I filesystem...
.LP
.B /usr/sbin/setquota
[
@@ -44,7 +44,7 @@ setquota \- set disk quotas
.I name
.B \-a
|
-.I filesystem
+.I filesystem...
.LP
.B /usr/sbin/setquota
.B \-t
@@ -61,7 +61,7 @@ setquota \- set disk quotas
.I inode-grace
.B \-a
|
-.I filesystem
+.I filesystem...
.SH DESCRIPTION
.IX "setquota command" "" "\fLsetquota\fP \(em set disk quotas"
.IX set "disk quotas \(em \fLsetquota\fP"
@@ -78,8 +78,16 @@ filesystem can be specified on the command line.
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.
+Perform setting for specified format (ie. don't perform format autodetection).
+Possible format names are:
+.B vfsold
+(version 1 quota),
+.B vfsv0
+(version 2 quota),
+.B rpc
+(quota over NFS),
+.B xfs
+(quota on XFS filesystem)
.TP
.B -u
Set user quotas for named user. This is the default.
diff --git a/setquota.c b/setquota.c
index 4f27ca8..8721766 100644
--- a/setquota.c
+++ b/setquota.c
@@ -29,6 +29,7 @@
int flags, fmt = -1;
char **mnt;
+char *progname;
int mntcnt;
qid_t protoid, id;
struct util_dqblk toset;
@@ -37,30 +38,30 @@ struct util_dqblk toset;
static void usage(void)
{
#if defined(RPC_SETQUOTA)
- fprintf(stderr, _("Usage:\n"
+ errstr(_("Usage:\n"
" setquota [-u|-g] [-r] [-F quotaformat] <user|group>\n"
"\t<block-softlimit> <block-hardlimit> <inode-softlimit> <inode-hardlimit> -a|<filesystem>...\n"
" setquota [-u|-g] [-r] [-F quotaformat] <-p protouser|protogroup> <user|group> -a|<filesystem>...\n"
" setquota [-u|-g] [-F quotaformat] -t <blockgrace> <inodegrace> -a|<filesystem>...\n"));
#else
- fprintf(stderr, _("Usage:\n"
+ errstr(_("Usage:\n"
" setquota [-u|-g] [-F quotaformat] <user|group>\n"
"\t<block-softlimit> <block-hardlimit> <inode-softlimit> <inode-hardlimit> -a|<filesystem>...\n"
" 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
- fprintf(stderr, _("Bugs to: %s\n"), MY_EMAIL);
+ errstr(_("Bugs to: %s\n"), MY_EMAIL);
exit(1);
}
-/* Convert string to number - print error message in case of failure */
+/* Convert string to number - print errstr message in case of failure */
static long parse_num(char *str, char *msg)
{
char *errch;
long ret = strtol(str, &errch, 0);
if (*errch) {
- fprintf(stderr, _("Bad %s: %s\n"), msg, str);
+ errstr(_("Bad %s: %s\n"), msg, str);
usage();
}
return ret;
@@ -216,18 +217,22 @@ int main(int argc, char **argv)
struct quota_handle **handles;
gettexton();
+ progname = basename(argv[0]);
+
parse_options(argc, argv);
warn_new_kernel(fmt);
if (flags & FL_ALL)
- handles = create_handle_list(0, NULL, flag2type(flags), fmt, !(flags & FL_RPC));
+ handles = create_handle_list(0, NULL, flag2type(flags), fmt, (flags & FL_RPC) ? 0 : IOI_LOCALONLY);
else
- handles = create_handle_list(mntcnt, mnt, flag2type(flags), fmt, !(flags & FL_RPC));
+ handles = create_handle_list(mntcnt, mnt, flag2type(flags), fmt, (flags & FL_RPC) ? 0 : IOI_LOCALONLY);
if (flags & FL_GRACE)
setgraces(handles);
else
setlimits(handles);
+
dispose_handle_list(handles);
+
return 0;
}
diff --git a/warnquota.c b/warnquota.c
index a4516d5..8c0a4de 100644
--- a/warnquota.c
+++ b/warnquota.c
@@ -10,7 +10,7 @@
*
* Author: Marco van Wieringen <mvw@planets.elm.net>
*
- * Version: $Id: warnquota.c,v 1.1 2001/03/23 12:03:27 jkar8572 Exp $
+ * Version: $Id: warnquota.c,v 1.2 2001/05/02 09:32:22 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
@@ -84,6 +84,7 @@ typedef struct quotatable {
} quotatable_t;
int qtab_i = 0;
+char *progname;
quotatable_t *quotatable = (quotatable_t *) NULL;
/*
@@ -273,7 +274,7 @@ void stripstring(char **buff)
/*
* Reads config parameters from configfile
- * uses default values if error occurs
+ * uses default values if errstr occurs
*/
void readconfigfile(const char *filename, struct configparams *config)
{
@@ -335,11 +336,12 @@ void readconfigfile(const char *filename, struct configparams *config)
strncpy(config->phone, value, CNF_BUFFER);
}
else { /* not matched at all */
- fprintf(stderr, "Error in config file (line %d), ignoring\n", line);
+ errstr( "Error in config file (line %d), ignoring\n",
+ line);
}
}
else { /* no '=' char in this line */
- fprintf(stderr, "Possible error in config file (line %d), ignoring\n",
+ errstr( "Possible error in config file (line %d), ignoring\n",
line);
}
}
@@ -358,7 +360,7 @@ void warn_quota(void)
readconfigfile(WARNQUOTA_CONF, &config);
- handles = create_handle_list(0, NULL, USRQUOTA, -1, 1);
+ handles = create_handle_list(0, NULL, USRQUOTA, -1, IOI_LOCALONLY | IOI_READONLY | IOI_OPENFILE);
for (i = 0; handles[i]; i++)
handles[i]->qh_ops->scan_dquots(handles[i], check_offence);
get_quotatable();
@@ -368,7 +370,10 @@ void warn_quota(void)
int main(int argc, char **argv)
{
gettexton();
+ progname = basename(argv[0]);
+
warn_new_kernel(-1);
warn_quota();
+
return 0;
}
diff --git a/xqmstats.c b/xqmstats.c
index 9de5434..88d824b 100644
--- a/xqmstats.c
+++ b/xqmstats.c
@@ -7,11 +7,14 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
+#include "common.h"
#include "pot.h"
#define XQMFILE "/proc/fs/xfs/xqm"
#define STATFILE "/proc/fs/xfs/stat"
+char *progname;
+
int main(int argc, char **argv)
{
FILE *stats, *xqm;
@@ -19,11 +22,12 @@ int main(int argc, char **argv)
unsigned values[8];
gettexton();
+ progname = basename(argv[0]);
memset(values, 0, sizeof(unsigned) * 8);
if ((stats = fopen(STATFILE, "r")) == NULL || (xqm = fopen(XQMFILE, "r")) == NULL) {
- fprintf(stderr, _("The running kernel does not support XFS\n"));
+ errstr(_("The running kernel does not support XFS\n"));
return 1;
}
while (!feof(stats)) {