summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)) {